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; }
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; }