public async Task CleanDepartedAsync(CommandContext ctx) { _logger.Debug($"Checking if there are any subscriptions for members that are no longer apart of the server..."); var removed = 0; var users = _dep.SubscriptionProcessor?.Manager?.Subscriptions;// GetUserSubscriptions(); for (var i = 0; i < users.Count; i++) { var user = users[i]; var discordUser = ctx.Client.GetMemberById(_dep.WhConfig.Discord.GuildId, user.UserId); var isSupporter = ctx.Client.HasSupporterRole(_dep.WhConfig.Discord.GuildId, user.UserId, _dep.WhConfig.Discord.DonorRoleIds); if (discordUser == null || !isSupporter) { _logger.Debug($"Removing user {user.UserId} subscription settings because they are no longer a member of the server."); if (!_dep.SubscriptionProcessor.Manager.RemoveAllUserSubscriptions(user.UserId)) { _logger.Warn($"Could not remove user {user.UserId} subscription settings from the database."); continue; } _logger.Info($"Removed {user.UserId} and subscriptions from database."); removed++; } } await ctx.RespondEmbed($"Removed {removed.ToString("N0")} of {users.Count.ToString("N0")} total members."); }
public async Task CleanDepartedAsync(CommandContext ctx) { _logger.Debug($"Checking if there are any subscriptions for members that are no longer apart of the server..."); var guildId = ctx.Guild?.Id ?? ctx.Client.Guilds.Keys.FirstOrDefault(x => _dep.WhConfig.Servers.ContainsKey(x)); var removed = 0; var users = _dep.SubscriptionProcessor?.Manager?.Subscriptions; for (var i = 0; i < users.Count; i++) { var user = users[i]; var discordUser = ctx.Client.GetMemberById(guildId, user.UserId); var isSupporter = ctx.Client.HasSupporterRole(guildId, user.UserId, _dep.WhConfig.Servers[guildId].DonorRoleIds); if (discordUser == null || !isSupporter) { _logger.Debug($"Removing user {user.UserId} subscription settings because they are no longer a member of the server."); if (!SubscriptionManager.RemoveAllUserSubscriptions(guildId, user.UserId)) { _logger.Warn($"Unable to remove user {user.UserId} subscription settings from the database."); continue; } _logger.Info($"Removed {user.UserId} and subscriptions from database."); removed++; } } await ctx.RespondEmbed(Translator.Instance.Translate("REMOVED_TOTAL_DEPARTED_MEMBERS").FormatText(removed.ToString("N0"), users.Count.ToString("N0"))); }
private void Http_PokemonReceived(object sender, DataReceivedEventArgs <PokemonData> e) { var pkmn = e.Data; if (DateTime.Now > pkmn.DespawnTime) { _logger.Debug($"Pokemon {pkmn.Id} already despawned at {pkmn.DespawnTime}"); return; } if (_config.EventPokemonIds.Contains(pkmn.Id) && _config.EventPokemonIds.Count > 0) { if (PokemonData.GetIV(pkmn.Attack, pkmn.Defense, pkmn.Stamina) < 90) { return; } } //if (e.Pokemon.IsDitto) //{ // // Ditto // var originalId = e.Pokemon.Id; // e.Pokemon.OriginalPokemonId = originalId; // e.Pokemon.Id = 132; // e.Pokemon.FormId = 0; //} ProcessPokemon(pkmn); OnPokemonSubscriptionTriggered(pkmn); }
private void Http_PokemonReceived(object sender, DataReceivedEventArgs <PokemonData> e) { var pkmn = e.Data; if (DateTime.Now > pkmn.DespawnTime) { _logger.Debug($"Pokemon {pkmn.Id} already despawned at {pkmn.DespawnTime}"); return; } // Check if Pokemon is in event Pokemon list if (_config.EventPokemonIds.Contains(pkmn.Id) && _config.EventPokemonIds.Count > 0) { //Skip Pokemon if no IV stats. if (pkmn.IsMissingStats) { return; } var iv = PokemonData.GetIV(pkmn.Attack, pkmn.Defense, pkmn.Stamina); //Skip Pokemon if IV is less than 90%, not 0%, and does not match any PvP league stats. if ((iv < 90 && iv != 0) || !pkmn.MatchesGreatLeague || !pkmn.MatchesUltraLeague) { return; } } ProcessPokemon(pkmn); OnPokemonSubscriptionTriggered(pkmn); }
private void Http_PokemonReceived(object sender, DataReceivedEventArgs <PokemonData> e) { var pkmn = e.Data; if (DateTime.UtcNow.ConvertTimeFromCoordinates(pkmn.Latitude, pkmn.Longitude) > pkmn.DespawnTime) { _logger.Debug($"Pokemon {pkmn.Id} already despawned at {pkmn.DespawnTime}"); return; } // Check if Pokemon is in event Pokemon list if (_config.Instance.EventPokemonIds.Contains(pkmn.Id) && _config.Instance.EventPokemonIds.Count > 0) { // Skip Pokemon if no IV stats. if (pkmn.IsMissingStats) { return; } var iv = PokemonData.GetIV(pkmn.Attack, pkmn.Defense, pkmn.Stamina); // Skip Pokemon if IV is greater than 0%, less than 90%, and does not match any PvP league stats. if (iv > 0 && iv < _config.Instance.EventMinimumIV && !pkmn.MatchesGreatLeague && !pkmn.MatchesUltraLeague) { return; } } ProcessPokemon(pkmn); OnPokemonSubscriptionTriggered(pkmn); }
public static Dictionary <string, Device> GetAll() { var devices = new Dictionary <string, Device>(); var output = Shell.Execute("ios-deploy", "-c device_identification", out var exitCode); if (string.IsNullOrEmpty(output))// || exitCode != 0) { // Failed return(devices); } var split = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); try { foreach (var line in split) { if (!line.ToLower().Contains("found")) { continue; } var uuid = line.GetBetween("Found ", " ("); var name = line.GetBetween("'", "'"); // Look for WiFi addresses since it's quick var ipData = Shell.Execute("ping", $"-t 1 {name}", out var ipExitCode); var ipAddress = ParseIPAddress(ipData); if (string.IsNullOrEmpty(ipAddress)) { // Look for tethered addresses and blanks. This takes a while //var tetherData = Shell.Execute("idevicesyslog", $"-u {uuid} -m '192.168.' -T 'IPv4'", out var tetherExitCode); //ipAddress = ParseIPAddress(tetherData); } _logger.Debug($"Found device {name} ({uuid}) {ipAddress}"); if (!devices.ContainsKey(name)) { devices.Add(name, new Device { Name = name, Uuid = uuid, IPAddress = ipAddress }); } } } catch (Exception ex) { _logger.Error($"ERROR: {ex}"); } return(devices); }
private async Task CheckSupporterStatus() { var owner = await _client.GetUser(_config.OwnerId); if (owner == null) { return; } foreach (var user in _config.Supporters) { var member = await _client.GetMemberFromUserId(user.Key); if (member == null) { _logger.Error($"Failed to find discord member with id {user.Key}."); continue; } if (!member.HasSupporterRole(_config.SupporterRoleId)) { continue; } if (!await _client.IsSupporterStatusExpired(_config, member.Id)) { continue; } _logger.Debug($"Removing supporter role from user {member.Id} because their time has expired..."); await _client.SendDirectMessage(owner, $"{member.Mention} (Alias: {member.Username}, Id: {member.Id}) supportor status has expired, please remove their role.", null); //if (_db.Subscriptions.Exists(x => x.UserId == member.Id)) //{ // _db.Subscriptions.Find(x => x.UserId == member.Id).Enabled = false; // _db.Save(); // _logger.Debug($"Disabled Pokemon and Raid notifications for user {member.Username} ({member.Id}) because their subscription has expired."); //} //if (!await _client.RemoveRole(member.Id, guild.Key, _config.SupporterRoleId)) //{ // _logger.Error($"Failed to remove supporter role from user {member.Id}."); // continue; //} _logger.Debug($"Successfully removed supporter role from user {member.Id}."); } }
public void UpdateOrganisationDetails(long organisationId) { _CustomLogger.Debug($"Loading organisation - OrganisationId({organisationId})"); var organisation = _DataRepository.Get <Organisation>(organisationId); _CustomLogger.Debug($"Updating LastCheckedAgainstCompaniesHouse - OrganisationId({organisationId})"); organisation.LastCheckedAgainstCompaniesHouse = VirtualDateTime.Now; _DataRepository.SaveChangesAsync().Wait(); try { _CustomLogger.Debug($"Calling CoHo API - OrganisationId({organisationId})"); var organisationFromCompaniesHouse = _CompaniesHouseAPI.GetCompanyAsync(organisation.CompanyNumber).Result; _CustomLogger.Debug($"Starting transaction - OrganisationId({organisationId})"); _DataRepository.BeginTransactionAsync( async() => { try { _CustomLogger.Debug($"Updating SIC codes - OrganisationId({organisationId})"); UpdateSicCode(organisation, organisationFromCompaniesHouse); _CustomLogger.Debug($"Updating Address - OrganisationId({organisationId})"); UpdateAddress(organisation, organisationFromCompaniesHouse); _CustomLogger.Debug($"Updating Name - OrganisationId({organisationId})"); UpdateName(organisation, organisationFromCompaniesHouse); _CustomLogger.Debug($"Saving - OrganisationId({organisationId})"); _DataRepository.SaveChangesAsync().Wait(); _DataRepository.CommitTransaction(); _CustomLogger.Debug($"Saved - OrganisationId({organisationId})"); } catch (Exception ex) { var message = $"Update from Companies House: Failed to update database, organisation id = {organisationId}"; _CustomLogger.Error(message, ex); _DataRepository.RollbackTransaction(); } }) .Wait(); } catch (Exception ex) { var message = $"Update from Companies House: Failed to get company data from companies house, organisation id = {organisationId}"; _CustomLogger.Error(message, ex); } }
/// <summary> /// Get all enabled user subscriptions /// </summary> /// <returns>Returns all enabled user subscription objects</returns> public List <SubscriptionObject> GetUserSubscriptions() { try { if (!IsDbConnectionOpen()) { throw new Exception("Not connected to database."); } var conn = GetConnection(); var where = conn? .From <SubscriptionObject>()? .Where(x => x.Status != NotificationStatusType.None); var results = conn? .LoadSelect(where)? .ToList(); return(results); } catch (OutOfMemoryException mex) { _logger.Debug($"-------------------OUT OF MEMORY EXCEPTION!"); _logger.Error(mex); Environment.FailFast($"Out of memory: {mex}"); } catch (Exception ex) { _logger.Error(ex); } return(null); }
public static async Task <Tuple <DiscordChannel, long> > DeleteMessages(this DiscordClient client, ulong channelId) { var deleted = 0L; DiscordChannel channel; try { channel = await client.GetChannelAsync(channelId); } catch (DSharpPlus.Exceptions.NotFoundException) { _logger.Debug($"Failed to get Discord channel {channelId}, skipping..."); return(null); } if (channel == null) { _logger.Warn($"Failed to find channel by id {channelId}, skipping..."); return(null); } var messages = await channel?.GetMessagesAsync(); if (messages == null) { return(null); } while (messages.Count > 0) { for (var j = 0; j < messages.Count; j++) { var message = messages[j]; if (message == null) { continue; } try { await message.DeleteAsync("Channel reset."); deleted++; } catch { continue; } } try { messages = await channel.GetMessagesAsync(); } catch (Newtonsoft.Json.JsonReaderException ex) { _logger.Error(ex); continue; } } return(Tuple.Create(channel, deleted)); }
/// <summary> /// Parses the provided command line parameters. /// </summary> /// <param name="prefixes"></param> /// <param name="args">The command line parameters to parse.</param> /// <returns>Returns a dictionary of key value pairs containing the parsed command line parameters.</returns> public static Dictionary <string, object> ParseArgs(string[] prefixes, string[] args) { _logger.Trace("CommandLine::ParseArgs"); var dict = new Dictionary <string, object>(); var prefixList = new List <string>(prefixes); for (int i = 0; i < args.Length; i++) { var prefix = GetPrefix(prefixes, args[i]); if (!string.IsNullOrEmpty(prefix)) { try { var key = args[i].Substring(prefix.Length, args[i].Length - prefix.Length); var isEnd = args.Length - 1 == i; var isCommand = !isEnd && args[i + 1].Contains(prefix); if (isCommand || isEnd) { dict.Add(key, true); //TODO: Provide better solution. continue; } var value = args[i + 1]; dict.Add(key, value); } catch (Exception ex) { _logger.Debug($"Failed to parse argument: {ex}"); } } } return(dict); }
public static string Execute(string cmd, string args, out int exitCode, bool includeErrorOutput = false) { var psi = new ProcessStartInfo { FileName = cmd, Arguments = args, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, WindowStyle = ProcessWindowStyle.Hidden }; var p = Process.Start(psi); var output = p.StandardOutput.ReadToEndAsync().GetAwaiter().GetResult(); if (includeErrorOutput) { output += '\n' + p.StandardError.ReadToEndAsync().GetAwaiter().GetResult(); } p.OutputDataReceived += (sender, e) => _logger.Debug($"[OUT] {e.Data}"); p.ErrorDataReceived += (sender, e) => _logger.Error($"[ERR] {e.Data}"); p.WaitForExit(); exitCode = p.ExitCode; return(output); }
public WeatherData GetWeatherConditions(string city) { _logger.Trace($"WeatherService::GetWeatherConditions [City={city}]"); //var conditions = GetWeatherConditions(); if (_weatherConditions == null) { return(null); } foreach (var condition in _weatherConditions) { if (condition == null) { _logger.Debug($"Weather condition for {condition.Location} was null."); continue; } var geofence = _geofenceSvc.GetGeofence(new Location(condition.Latitude, condition.Longitude)); if (geofence == null) { continue; } if (string.Compare(geofence.Name, city) == 0) { return(condition); } } return(null); }
private int FindPokemon(string pokemon) { _logger.Debug($"Name Before: {pokemon}"); var db = Database.Instance; var pkmn = db.Pokemon.FirstOrDefault(x => string.Compare(x.Value, pokemon, true) == 0).Value; if (pkmn == null) { pkmn = db.Pokemon.FirstOrDefault(x => LevenshteinDistance.Compute(x.Value, pokemon) <= 2).Value; } _logger.Debug($"Name After: {pkmn}"); var pokeId = db.PokemonIdFromName(pkmn ?? string.Empty); return(pokeId); }
public async Task ReopenAsync(CommandContext ctx, [Description("iPhone names i.e. `iPhoneHV1SE`. Comma delimiter supported `iPhoneHV1SE,iPhoneHV2SE`"), RemainingText] string phoneNames = Strings.All) { if (!ctx.Member.HasRequiredRoles(_dep.Config.RequiredRoles)) { await ctx.RespondAsync($":no_entry: {ctx.User.Username} Unauthorized permissions."); return; } if (!ctx.Channel.Id.IsValidChannel(_dep.Config.ChannelIds)) { return; } var devices = Device.GetAll(); var reopenDevices = phoneNames.RemoveSpaces(); if (string.Compare(phoneNames, Strings.All, true) == 0) { reopenDevices = devices.Keys.ToArray(); } foreach (var name in reopenDevices) { if (!devices.ContainsKey(name)) { _logger.Warn($"{name} does not exist in device list, skipping reboot."); continue; } var device = devices[name]; _logger.Debug($"Using IP address '{device.IPAddress}' to send restart game request to {device.Name}"); // Check if we have IP address for device if (string.IsNullOrEmpty(device.IPAddress)) { await ctx.RespondAsync($"Failed to get IP address for device {device.Name} ({device.Uuid}) to restart game"); continue; } // Send HTTP GET request to device IP address var data = NetUtils.Get($"http://{device.IPAddress}:8080/restart"); await ctx.RespondAsync ( string.IsNullOrEmpty(data) ?$"Reopening game for device {device.Name} ({device.Uuid})" : $"Error response: {data}" ); } }
public async Task GetReminders(DiscordMessage message) { try { if (!_db.Reminders.ContainsKey(message.Author.Id)) { await message.RespondAsync($"{message.Author.Mention} does not have any reminders set."); return; } if (_db.Reminders.Count == 0) { await message.RespondAsync($"{message.Author.Mention} does not have any reminders set."); return; } var orderedReminders = _db.Reminders[message.Author.Id].OrderBy(x => x.Time).ToList(); var eb = new DiscordEmbedBuilder { Color = new DiscordColor(4, 97, 247), ThumbnailUrl = message.Author.AvatarUrl, Title = $"{message.Author.Username}, your reminders are the following:" }; for (int i = 0; i < orderedReminders.Count && i < 10; i++) { var msg = $"Reminder #{i + 1} in {ReminderSvc.ConvertTime(orderedReminders[i].Time.Subtract(DateTime.UtcNow).TotalSeconds)}"; _logger.Debug($"{msg}: {orderedReminders[i].Message}"); var channel = orderedReminders[i].Where == 0 ? null : await _client.GetChannel(orderedReminders[i].Where); eb.AddField(msg, $"{(channel?.Name ?? "DM")}: {orderedReminders[i].Message}"); } var embed = eb.Build(); if (embed == null) { return; } await message.RespondAsync(message.Author.Mention, false, embed); } catch (Exception ex) { _logger.Error(ex); } }
private bool SetEncounterList(string mapPath, string feedName, WeatherType weather) { _logger.Trace($"SetEncounterListCommand::SwitchEncounterList [MapPath={mapPath}, FeedName={feedName}, WeatherType={weather}]"); _logger.Debug($"Attempting to switch encounter list for feed {feedName} to {weather}..."); var encounterList = "enc-whitelist-rares"; var cityEncounterListFilePath = Path.Combine(mapPath, $"{encounterList}-{feedName}.txt"); if (!File.Exists(cityEncounterListFilePath)) { _logger.Error($"Specified city encounter list does not exist at path {cityEncounterListFilePath}..."); return(false); } var weatherEncounterListFilePath = Path.Combine(mapPath, $"{encounterList} - {weather}.txt"); if (!File.Exists(weatherEncounterListFilePath)) { _logger.Error($"Specified weather encounter list does not exist at path {weatherEncounterListFilePath}..."); return(false); } var weatherEncounterList = File.ReadAllLines(weatherEncounterListFilePath); if (weatherEncounterList.Length == 0) { _logger.Error($"Encounter list is empty, aborting..."); return(false); } _logger.Debug("Writing new weather encounter list..."); File.WriteAllLines(cityEncounterListFilePath, weatherEncounterList); _logger.Debug($"Successfully switched encounter list for feed {feedName} to {weather}..."); return(true); }
public Bot(Config config) { var name = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName; _logger = EventLogger.GetLogger(name); _logger.Trace($"Bot::Bot [GuildId={config.GuildId}, OwnerId={config.OwnerId}]"); _config = config; #pragma warning disable RECS0165 // Asynchronous methods should return a Task instead of void AppDomain.CurrentDomain.UnhandledException += async(sender, e) => #pragma warning restore RECS0165 // Asynchronous methods should return a Task instead of void { _logger.Debug("Unhandled exception caught."); _logger.Error((Exception)e.ExceptionObject); if (e.IsTerminating) { if (_client != null) { var owner = await _client.GetUserAsync(_config.OwnerId); if (owner == null) { _logger.Warn($"Failed to get owner from id {_config.OwnerId}."); return; } await _client.SendDirectMessage(owner, Strings.CrashMessage, null); } } }; _client = new DiscordClient(new DiscordConfiguration { AutomaticGuildSync = true, AutoReconnect = true, EnableCompression = true, Token = _config.Token, TokenType = TokenType.Bot, UseInternalLogHandler = true }); _client.Ready += Client_Ready; _client.MessageReactionAdded += Client_MessageReactionAdded; _client.ClientErrored += Client_ClientErrored; _client.DebugLogger.LogMessageReceived += DebugLogger_LogMessageReceived; _lobbyManager = new RaidLobbyManager(_client, _config); }
public TweetService(DiscordClient client, Config config, IEventLogger logger) { _client = client; _config = config; _logger = logger; _timer = new Timer { Interval = 1000 * 60 * 5 }; _timer.Elapsed += MinuteTimerEventHandler; var creds = SetCredentials(_config.TwitterUpdates); _twitterStream = Stream.CreateFilteredStream(creds); _twitterStream.Credentials = creds; _twitterStream.StallWarnings = true; _twitterStream.FilterLevel = StreamFilterLevel.None; _twitterStream.StreamStarted += (sender, e) => _logger.Debug("Successfully started."); _twitterStream.StreamStopped += (sender, e) => _logger.Debug($"Stream stopped.\r\n{e.Exception}\r\n{e.DisconnectMessage}"); _twitterStream.DisconnectMessageReceived += (sender, e) => _logger.Debug($"Disconnected.\r\n{e.DisconnectMessage}"); _twitterStream.WarningFallingBehindDetected += (sender, e) => _logger.Debug($"Warning Falling Behind Detected: {e.WarningMessage}"); CheckTwitterFollows(); }
private async void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e) { _logger.Debug("Unhandled exception caught."); _logger.Error((Exception)e.ExceptionObject); if (e.IsTerminating) { var keys = _whConfig.Servers.Keys.ToList(); for (var i = 0; i < keys.Count; i++) { var guildId = keys[i]; if (!_whConfig.Servers.ContainsKey(guildId)) { _logger.Error($"Unable to find guild id {guildId} in server config list."); continue; } var server = _whConfig.Servers[guildId]; if (!_servers.ContainsKey(guildId)) { _logger.Error($"Unable to find guild id {guildId} in Discord server client list."); continue; } var client = _servers[guildId]; if (client != null) { var owner = await client.GetUserAsync(server.OwnerId); if (owner == null) { _logger.Warn($"Unable to get owner from id {server.OwnerId}."); return; } // TODO: await client.SendDirectMessage(owner, Strings.CrashMessage, null); } } } }
public Bot(WhConfig whConfig, string alarmsFilePath) { _logger.Trace($"WhConfig={whConfig.Discord.GuildId}, OwnerId={whConfig.Discord.OwnerId}, GuildId={whConfig.Discord.GuildId}, WebhookPort={whConfig.WebhookPort}"); _lang = new Translator(); _whConfig = whConfig; DataAccessLayer.ConnectionString = _whConfig.ConnectionStrings.Main; DataAccessLayer.ScannerConnectionString = _whConfig.ConnectionStrings.Scanner; AppDomain.CurrentDomain.UnhandledException += async(sender, e) => { _logger.Debug("Unhandled exception caught."); _logger.Error((Exception)e.ExceptionObject); if (e.IsTerminating) { if (_client != null) { var owner = await _client.GetUserAsync(_whConfig.Discord.OwnerId); if (owner == null) { _logger.Warn($"Failed to get owner from id {_whConfig.Discord.OwnerId}."); return; } await _client.SendDirectMessage(owner, Strings.CrashMessage, null); } } }; _gyms = new Dictionary <string, GymDetailsData>(); _whm = new WebhookManager(_whConfig, alarmsFilePath); _whm.PokemonAlarmTriggered += OnPokemonAlarmTriggered; _whm.RaidAlarmTriggered += OnRaidAlarmTriggered; _whm.QuestAlarmTriggered += OnQuestAlarmTriggered; _whm.PokestopAlarmTriggered += OnPokestopAlarmTriggered; _whm.GymAlarmTriggered += OnGymAlarmTriggered; _whm.GymDetailsAlarmTriggered += OnGymDetailsAlarmTriggered; _whm.WeatherAlarmTriggered += OnWeatherAlarmTriggered; if (_whConfig.Discord.EnableSubscriptions) { _whm.PokemonSubscriptionTriggered += OnPokemonSubscriptionTriggered; _whm.RaidSubscriptionTriggered += OnRaidSubscriptionTriggered; _whm.QuestSubscriptionTriggered += OnQuestSubscriptionTriggered; _whm.InvasionSubscriptionTriggered += OnInvasionSubscriptionTriggered; } _logger.Info("WebhookManager is running..."); var midnight = new DandTSoftware.Timers.MidnightTimer(); midnight.TimeReached += async(e) => await ResetQuests(); midnight.Start(); _client = new DiscordClient(new DiscordConfiguration { AutomaticGuildSync = true, AutoReconnect = true, EnableCompression = true, Token = _whConfig.Discord.Token, TokenType = TokenType.Bot, UseInternalLogHandler = true }); _client.Ready += Client_Ready; //_client.MessageCreated += Client_MessageCreated; _client.ClientErrored += Client_ClientErrored; _client.DebugLogger.LogMessageReceived += DebugLogger_LogMessageReceived; _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), //TODO: Set prod // default timeout for other actions to 2 minutes Timeout = TimeSpan.FromMinutes(2) //TODO: Set prod } ); if (_whConfig.Discord.EnableSubscriptions) { _subProcessor = new SubscriptionProcessor(_client, _whConfig, _whm); } DependencyCollection dep; using (var d = new DependencyCollectionBuilder()) { d.AddInstance(_dep = new Dependencies(_interactivity, _whm, _subProcessor, _whConfig, _lang, new StripeService(_whConfig.StripeApiKey))); dep = d.Build(); } _commands = _client.UseCommandsNext ( new CommandsNextConfiguration { StringPrefix = _whConfig.Discord.CommandPrefix?.ToString(), EnableDms = true, EnableMentionPrefix = string.IsNullOrEmpty(_whConfig.Discord.CommandPrefix), EnableDefaultHelp = false, CaseSensitive = false, IgnoreExtraArguments = true, Dependencies = dep } ); _commands.CommandExecuted += Commands_CommandExecuted; _commands.CommandErrored += Commands_CommandErrored; _commands.RegisterCommands <Owner>(); _commands.RegisterCommands <CommunityDay>(); _commands.RegisterCommands <Nests>(); _commands.RegisterCommands <ShinyStats>(); _commands.RegisterCommands <Gyms>(); _commands.RegisterCommands <Quests>(); if (_whConfig.Discord.EnableSubscriptions) { _commands.RegisterCommands <Notifications>(); } if (_whConfig.Discord.EnableCities) { _commands.RegisterCommands <Feeds>(); } }
/// <summary> /// Migrate the database from a specified version to the next version /// </summary> /// <param name="fromVersion">Database version to migrate from</param> /// <param name="toVersion">Database version to migrate to</param> /// <returns></returns> private async Task Migrate(int fromVersion, int toVersion) { if (fromVersion < toVersion) { // Wait 30 seconds and let user know we are about to migrate the database and for them to make // a backup until we handle backups and rollbacks. _logger.Info("MIGRATION IS ABOUT TO START IN 30 SECONDS, PLEASE MAKE SURE YOU HAVE A BACKUP!!!"); Thread.Sleep(30 * 1000); _logger.Info($"Migrating database to version {fromVersion + 1}"); var sqlFile = Path.Combine(MigrationsFolder, (fromVersion + 1) + ".sql"); // Read SQL file and remove any new lines var migrateSql = File.ReadAllText(sqlFile)?.Replace("\r", "").Replace("\n", ""); // If the migration file contains multiple queries, split them up var sqlSplit = migrateSql.Split(';'); // Loop through the migration queries foreach (var sql in sqlSplit) { // If the SQL query is null, skip... if (string.IsNullOrEmpty(sql)) { continue; } try { // Execute the SQL query var result = await Execute(sql); if (result != 0) { // Failed to execute query _logger.Warn($"Failed to execute migration: {sql}"); continue; } _logger.Debug($"Migration execution result: {result}"); } catch (Exception ex) { _logger.Error($"Migration failed: {ex}"); } } // Take a break Thread.Sleep(2000); // Build query to update metadata table version key var newVersion = fromVersion + 1; var updateVersionSQL = string.Format(Strings.SQL_INSERT_METADATA_FORMAT, newVersion); try { // Execute update version SQL var result = await Execute(updateVersionSQL); if (result > 0) { // Success } _logger.Debug($"Result: {result}"); } catch (Exception ex) { _logger.Error($"Migration failed: {ex}"); Environment.Exit(-1); } _logger.Info("Migration successful"); await Migrate(newVersion, toVersion); } if (fromVersion == toVersion) { _logger.Info("Migration done"); Finished = true; } await Task.CompletedTask; }
private void ParseRaid(dynamic message) { try { //| Field | Details | Example | | ———— | —————————————————————– | ———— | //gym_id | The gym’s unique ID | "NGY2ZjBjY2Y3OTUyNGQyZWFlMjc3ODkzODM2YmI1Y2YuMTY=" | //latitude | The gym’s latitude | 43.599321 | //longitude | The gym’s longitude | 5.181415 | //spawn | The time at which the raid spawned | 1500992342 | //start | The time at which the raid starts | 1501005600 | //end | The time at which the raid ends | 1501007400 | //level | The raid’s level | 5 | //pokemon_id | The raid boss’s ID | 249 | //cp | The raid boss’s CP | 42753 | //move_1 | The raid boss’s quick move | 274 | //move_2 | The raid boss’s charge move | 275 | if (message["pokemon_id"] == null) { Console.WriteLine("Raid Egg found, skipping..."); return; } var gymId = Convert.ToString(message["gym_id"]); var teamId = Convert.ToInt32(Convert.ToString(message["team_id"] ?? "0")); var latitude = Convert.ToDouble(Convert.ToString(message["latitude"])); var longitude = Convert.ToDouble(Convert.ToString(message["longitude"])); var spawn = Convert.ToInt64(Convert.ToString(message["spawn"])); var start = Convert.ToInt64(Convert.ToString(message["start"])); //"raid_begin"])); var end = Convert.ToInt64(Convert.ToString(message["end"])); //"raid_end"])); var level = Convert.ToString(message["level"] ?? "?"); var pokemonId = Convert.ToInt32(Convert.ToString(message["pokemon_id"] ?? 0)); var cp = Convert.ToString(message["cp"] ?? "?"); var move1 = Convert.ToString(message["move_1"] ?? "?"); var move2 = Convert.ToString(message["move_2"] ?? "?"); if (pokemonId == 0) { _logger.Debug($"Level {level} Egg, skipping..."); return; } var raid = new RaidData ( pokemonId, (PokemonTeam)teamId, level, cp, move1, move2, latitude, longitude, Utils.FromUnix(start), Utils.FromUnix(end) ); OnRaidReceived(raid); } catch (Exception ex) { Utils.LogError(ex); _logger.Error(ex.StackTrace); _logger.Info("{0}", Convert.ToString(message)); } }
/// <summary> /// Migrate the database from a specified version to the next version /// </summary> /// <param name="fromVersion">Database version to migrate from</param> /// <param name="toVersion">Database version to migrate to</param> /// <returns></returns> private async Task Migrate(int fromVersion, int toVersion) { if (fromVersion < toVersion) { _logger.Info($"Migrating database to version {fromVersion + 1}"); var sqlFile = Path.Combine(MigrationsFolder, (fromVersion + 1) + ".sql"); // Read SQL file and remove any new lines var migrateSql = File.ReadAllText(sqlFile)?.Replace("\r", "").Replace("\n", ""); // If the migration file contains multiple queries, split them up var sqlSplit = migrateSql.Split(';'); // Loop through the migration queries foreach (var sql in sqlSplit) { // If the SQL query is null, skip... if (string.IsNullOrEmpty(sql)) { continue; } try { // Execute the SQL query var result = await Execute(sql); if (result != 0) { // Failed to execute query _logger.Warn($"Failed to execute migration: {sql}"); continue; } _logger.Debug($"Migration execution result: {result}"); } catch (Exception ex) { _logger.Error($"Migration failed: {ex}"); } } // Take a break Thread.Sleep(2000); // Build query to update metadata table version key var newVersion = fromVersion + 1; try { // Execute update version SQL var result = SetCurrentVersion(newVersion); if (result) { // Success } _logger.Debug($"Result: {result}"); } catch (Exception ex) { _logger.Error($"Migration failed: {ex}"); Environment.Exit(-1); } _logger.Info("Migration successful"); await Migrate(newVersion, toVersion); } if (fromVersion == toVersion) { _logger.Info("Migration done"); Finished = true; } await Task.CompletedTask; }
public async Task ProcessPokemonSubscription(PokemonData pkmn) { if (!MasterFile.Instance.Pokedex.ContainsKey(pkmn.Id)) { return; } var loc = _whm.GetGeofence(pkmn.Latitude, pkmn.Longitude); if (loc == null) { //_logger.Warn($"Failed to lookup city from coordinates {pkmn.Latitude},{pkmn.Longitude} {db.Pokemon[pkmn.Id].Name} {pkmn.IV}, skipping..."); return; } var subscriptions = Manager.GetUserSubscriptionsByPokemonId(pkmn.Id); if (subscriptions == null) { _logger.Warn($"Failed to get subscriptions from database table."); return; } SubscriptionObject user; PokemonSubscription subscribedPokemon; DiscordMember member = null; var pokemon = MasterFile.GetPokemon(pkmn.Id, pkmn.FormId); var matchesIV = false; var matchesLvl = false; var matchesGender = false; var matchesIVList = false; for (var i = 0; i < subscriptions.Count; i++) { try { user = subscriptions[i]; if (user == null) { continue; } if (!user.Enabled) { continue; } if (!_whConfig.Servers.ContainsKey(user.GuildId)) { continue; } if (!_whConfig.Servers[user.GuildId].EnableSubscriptions) { continue; } if (!_servers.ContainsKey(user.GuildId)) { continue; } var client = _servers[user.GuildId]; try { member = await client.GetMemberById(user.GuildId, user.UserId); } catch (Exception ex) { _logger.Debug($"FAILED TO GET MEMBER BY ID {user.UserId}"); _logger.Error(ex); continue; } if (!member.HasSupporterRole(_whConfig.Servers[user.GuildId].DonorRoleIds)) { _logger.Debug($"User {member?.Username} ({user.UserId}) is not a supporter, skipping pokemon {pokemon.Name}..."); continue; } if (member?.Roles == null || loc == null) { continue; } if (!member.Roles.Select(x => x?.Name?.ToLower()).Contains(loc?.Name?.ToLower())) { //_logger.Info($"User {member.Username} does not have city role {loc.Name}, skipping pokemon {pokemon.Name}."); continue; } /* * var exists = user.Pokemon.Exists(x => string.IsNullOrEmpty(x.City) || (!string.IsNullOrEmpty(x.City) && string.Compare(loc.Name, x.City, true) == 0)); * if (!exists) * { * //_logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for Pokemon {pokemon.PokemonId} because the Pokemon is in city '{loc.Name}'."); * continue; * } */ // Only check distance if user has it set if (user.DistanceM > 0) { var distance = new Coordinates(user.Latitude, user.Longitude).DistanceTo(new Coordinates(pkmn.Latitude, pkmn.Longitude)); if (user.DistanceM < distance) { //Skip if distance is set and is not with specified distance. _logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for Pokemon {pokemon.Name}, Pokemon is farther than set distance of '{user.DistanceM} meters."); continue; } } var form = Translator.Instance.GetFormName(pkmn.FormId); subscribedPokemon = user.Pokemon.FirstOrDefault(x => x.PokemonId == pkmn.Id && (string.IsNullOrEmpty(x.Form) || string.Compare(x.Form, form, true) == 0) && (string.IsNullOrEmpty(x.City) || (!string.IsNullOrEmpty(x.City) && string.Compare(loc.Name, x.City, true) == 0)) ); if (subscribedPokemon == null) { //_logger.Info($"User {member.Username} not subscribed to Pokemon {pokemon.Name} (Form: {form})."); continue; } matchesIV = Filters.MatchesIV(pkmn.IV, subscribedPokemon.MinimumIV); //var matchesCP = _whm.Filters.MatchesCpFilter(pkmn.CP, subscribedPokemon.MinimumCP); matchesLvl = Filters.MatchesLvl(pkmn.Level, (uint)subscribedPokemon.MinimumLevel, (uint)subscribedPokemon.MaximumLevel); matchesGender = Filters.MatchesGender(pkmn.Gender, subscribedPokemon.Gender); matchesIVList = subscribedPokemon.IVList?.Contains($"{pkmn.Attack}/{pkmn.Defense}/{pkmn.Stamina}") ?? false; if (!( (/*!subscribedPokemon.HasStats && */ matchesIV && matchesLvl && matchesGender) || (subscribedPokemon.HasStats && matchesIVList) )) { continue; } var embed = await pkmn.GeneratePokemonMessage(user.GuildId, client, _whConfig, null, loc.Name); foreach (var emb in embed.Embeds) { _queue.Enqueue(new NotificationItem(user, member, emb, pokemon.Name, loc.Name, pkmn)); } Statistics.Instance.SubscriptionPokemonSent++; Thread.Sleep(5); } catch (Exception ex) { _logger.Error(ex); } } subscriptions.Clear(); subscriptions = null; member = null; user = null; loc = null; pokemon = null; await Task.CompletedTask; }
private async Task CreateEmojis(ulong guildId) { _logger.Trace($"CreateEmojis"); if (!_servers.ContainsKey(guildId)) { _logger.Warn($"Discord client not ready yet to create emojis for guild {guildId}"); return; } var server = _whConfig.Servers[guildId]; var client = _servers[guildId]; if (!(client.Guilds?.ContainsKey(server.EmojiGuildId) ?? false)) { _logger.Warn($"Bot not in emoji server {server.EmojiGuildId}"); return; } var guild = client.Guilds[server.EmojiGuildId]; for (var j = 0; j < Strings.EmojiList.Length; j++) { try { var emoji = Strings.EmojiList[j]; var emojis = await guild.GetEmojisAsync(); var emojiExists = emojis.FirstOrDefault(x => string.Compare(x.Name, emoji, true) == 0); if (emojiExists == null) { _logger.Debug($"Emoji {emoji} doesn't exist, creating..."); var emojiPath = Path.Combine(Strings.EmojisFolder, emoji + ".png"); if (!File.Exists(emojiPath)) { _logger.Error($"Unable to find emoji file at {emojiPath}, skipping..."); continue; } var fs = new FileStream(emojiPath, FileMode.Open, FileAccess.Read); await guild.CreateEmojiAsync(emoji, fs, null, $"Missing `{emoji}` emoji."); _logger.Info($"Emoji {emoji} created successfully."); } } catch (Exception ex) { _logger.Error(ex); } } await LoadEmojis(); }
public async Task ProcessPokemonSubscription(PokemonData pkmn) { if (!MasterFile.Instance.Pokedex.ContainsKey(pkmn.Id)) { return; } // Cache the result per-guild so that geospatial stuff isn't queried for every single subscription below Dictionary <ulong, GeofenceItem> locationCache = new Dictionary <ulong, GeofenceItem>(); GeofenceItem GetGeofence(ulong guildId) { if (!locationCache.TryGetValue(guildId, out var geofence)) { geofence = _whm.GetGeofence(guildId, pkmn.Latitude, pkmn.Longitude); locationCache.Add(guildId, geofence); } return(geofence); } var subscriptions = Manager.GetUserSubscriptionsByPokemonId(pkmn.Id); if (subscriptions == null) { _logger.Warn($"Failed to get subscriptions from database table."); return; } SubscriptionObject user; PokemonSubscription subscribedPokemon; DiscordMember member = null; var pokemon = MasterFile.GetPokemon(pkmn.Id, pkmn.FormId); var matchesIV = false; var matchesLvl = false; var matchesGender = false; var matchesIVList = false; for (var i = 0; i < subscriptions.Count; i++) { //var start = DateTime.Now; try { user = subscriptions[i]; if (user == null) { continue; } if (!user.Enabled) { continue; } if (!_whConfig.Instance.Servers.ContainsKey(user.GuildId)) { continue; } if (!_whConfig.Instance.Servers[user.GuildId].Subscriptions.Enabled) { continue; } if (!_servers.ContainsKey(user.GuildId)) { continue; } var client = _servers[user.GuildId]; try { member = await client.GetMemberById(user.GuildId, user.UserId); } catch (Exception ex) { _logger.Debug($"FAILED TO GET MEMBER BY ID {user.UserId}"); _logger.Error(ex); continue; } if (member?.Roles == null) { continue; } if (!member.HasSupporterRole(_whConfig.Instance.Servers[user.GuildId].DonorRoleIds)) { _logger.Debug($"User {member?.Username} ({user.UserId}) is not a supporter, skipping pokemon {pokemon.Name}..."); // Automatically disable users subscriptions if not supporter to prevent issues //user.Enabled = false; //user.Save(false); continue; } var form = Translator.Instance.GetFormName(pkmn.FormId); subscribedPokemon = user.Pokemon.FirstOrDefault(x => x.PokemonId == pkmn.Id && (string.IsNullOrEmpty(x.Form) || (!string.IsNullOrEmpty(x.Form) && string.Compare(x.Form, form, true) == 0)) ); // Not subscribed to Pokemon if (subscribedPokemon == null) { //_logger.Debug($"User {member.Username} not subscribed to Pokemon {pokemon.Name} (Form: {form})."); continue; } matchesIV = Filters.MatchesIV(pkmn.IV, subscribedPokemon.MinimumIV); //var matchesCP = _whm.Filters.MatchesCpFilter(pkmn.CP, subscribedPokemon.MinimumCP); matchesLvl = Filters.MatchesLvl(pkmn.Level, (uint)subscribedPokemon.MinimumLevel, (uint)subscribedPokemon.MaximumLevel); matchesGender = Filters.MatchesGender(pkmn.Gender, subscribedPokemon.Gender); matchesIVList = subscribedPokemon.IVList?.Contains($"{pkmn.Attack}/{pkmn.Defense}/{pkmn.Stamina}") ?? false; if (!( (!subscribedPokemon.HasStats && matchesIV && matchesLvl && matchesGender) || (subscribedPokemon.HasStats && matchesIVList) )) { continue; } var geofence = GetGeofence(user.GuildId); if (geofence == null) { //_logger.Warn($"Failed to lookup city from coordinates {pkmn.Latitude},{pkmn.Longitude} {db.Pokemon[pkmn.Id].Name} {pkmn.IV}, skipping..."); continue; } var distanceMatches = user.DistanceM > 0 && user.DistanceM > new Coordinates(user.Latitude, user.Longitude).DistanceTo(new Coordinates(pkmn.Latitude, pkmn.Longitude)); var geofenceMatches = subscribedPokemon.Areas.Select(x => x.ToLower()).Contains(geofence.Name.ToLower()); // If set distance does not match and no geofences match, then skip Pokemon... if (!distanceMatches && !geofenceMatches) { continue; } var embed = pkmn.GeneratePokemonMessage(user.GuildId, client, _whConfig.Instance, null, geofence.Name); //var end = DateTime.Now.Subtract(start); //_logger.Debug($"Took {end} to process Pokemon subscription for user {user.UserId}"); embed.Embeds.ForEach(x => _queue.Enqueue(new NotificationItem(user, member, x, pokemon.Name, geofence.Name, pkmn))); Statistics.Instance.SubscriptionPokemonSent++; Thread.Sleep(5); } catch (Exception ex) { _logger.Error(ex); } } subscriptions.Clear(); subscriptions = null; member = null; user = null; pokemon = null; await Task.CompletedTask; }
public async Task DeployPoGoAsync(CommandContext ctx, [Description("iPhone names i.e. `iPhoneAB1SE`. Comma delimiter supported `iPhoneAB1SE,iPhoneCD2SE`"), RemainingText] string phoneNames = Strings.All) { if (!ctx.Member.HasRequiredRoles(_dep.Config.RequiredRoles)) { await ctx.RespondAsync($":no_entry: {ctx.User.Username} Unauthorized permissions."); return; } if (!ctx.Channel.Id.IsValidChannel(_dep.Config.ChannelIds)) { return; } var devices = Device.GetAll(); var deployAppDevices = new List <string>(phoneNames.RemoveSpaces()); if (string.Compare(phoneNames, Strings.All, true) == 0) { deployAppDevices = devices.Keys.ToList(); } var appPath = IpaDeployer.GetLatestAppPath(); if (string.IsNullOrEmpty(appPath)) { await ctx.RespondAsync($"No signed app found, make sure to run 'resign' command first."); return; } var deployer = new IpaDeployer(_dep.Config.Developer, _dep.Config.ProvisioningProfile); _logger.Debug($"Using app {appPath} for deployment."); //deployer.Deploy(appPath); Parallel.ForEach(deployAppDevices, async deviceName => { if (!devices.ContainsKey(deviceName)) { _logger.Warn($"{deviceName} does not exist in device list, skipping deploy pogo."); } else { var device = devices[deviceName]; var args = $"--id {device.Uuid} --bundle {appPath}"; _logger.Info($"Deploying to device {device.Name} ({device.Uuid})..."); var output = Shell.Execute("ios-deploy", args, out var exitCode, true); _logger.Debug($"{device.Name} ({device.Uuid}) Deployment output: {output}"); var success = output.ToLower().Contains($"[100%] installed package {appPath}"); if (success) { await ctx.RespondAsync($"Deployed {appPath} to {device.Name} ({device.Uuid}) successfully."); } else { if (output.Length > 2000) { output = string.Join("", output.TakeLast(1900)); } await ctx.RespondAsync($"Failed to deploy {appPath} to {device.Name} ({device.Uuid})\nOutput: {output}"); } } }); }
public Bot(Config config) { _logger.Trace($"WhConfig [OwnerId={config.OwnerId}, GuildId={config.GuildId}, Devices={config.Devices.Count}]"); _config = config; AppDomain.CurrentDomain.UnhandledException += async(sender, e) => { _logger.Debug("Unhandled exception caught."); _logger.Error((Exception)e.ExceptionObject); if (e.IsTerminating) { if (_client != null) { var owner = await _client.GetUserAsync(_config.OwnerId); if (owner == null) { _logger.Warn($"Failed to get owner from id {_config.OwnerId}."); return; } await _client.SendDirectMessage(owner, Strings.CrashMessage, null); } } }; _client = new DiscordClient(new DiscordConfiguration { AutomaticGuildSync = true, AutoReconnect = true, EnableCompression = true, Token = _config.Token, TokenType = TokenType.Bot, UseInternalLogHandler = true }); _client.Ready += Client_Ready; //_client.MessageCreated += Client_MessageCreated; _client.ClientErrored += Client_ClientErrored; _client.DebugLogger.LogMessageReceived += DebugLogger_LogMessageReceived; DependencyCollection dep; using (var d = new DependencyCollectionBuilder()) { d.AddInstance(new Dependencies(_config)); dep = d.Build(); } _commands = _client.UseCommandsNext ( new CommandsNextConfiguration { StringPrefix = _config.CommandPrefix?.ToString(), EnableDms = true, EnableMentionPrefix = string.IsNullOrEmpty(_config.CommandPrefix), EnableDefaultHelp = false, CaseSensitive = false, IgnoreExtraArguments = true, Dependencies = dep } ); _commands.CommandExecuted += Commands_CommandExecuted; _commands.CommandErrored += Commands_CommandErrored; _commands.RegisterCommands <PhoneControl>(); }
private async Task Client_GuildMemberUpdated(GuildMemberUpdateEventArgs e) { if (!_whConfig.Instance.Servers.ContainsKey(e.Guild.Id)) { return; } var server = _whConfig.Instance.Servers[e.Guild.Id]; if (!server.EnableCities) { return; } if (!server.AutoRemoveCityRoles) { return; } var hasBefore = e.RolesBefore.FirstOrDefault(x => server.DonorRoleIds.Contains(x.Id)) != null; var hasAfter = e.RolesAfter.FirstOrDefault(x => server.DonorRoleIds.Contains(x.Id)) != null; // Check if donor role was removed if (hasBefore && !hasAfter) { _logger.Info($"Member {e.Member.Username} ({e.Member.Id}) donor role removed, removing any city roles..."); // If so, remove all city/geofence/area roles foreach (var roleName in server.CityRoles) { var role = e.Guild.GetRoleFromName(roleName); if (role == null) { _logger.Debug($"Failed to get role by name {roleName}"); continue; } await e.Member.RevokeRoleAsync(role, "No longer a supporter/donor"); } _logger.Info($"All city roles removed from member {e.Member.Username} ({e.Member.Id})"); } }