Exemplo n.º 1
0
        public static string GetRaidEggIcon(this RaidData raid, WhConfig whConfig, string style)
        {
            var iconStyleUrl = whConfig.IconStyles[style];
            var url          = iconStyleUrl.EndsWith('/') ? iconStyleUrl + "eggs" : $"{iconStyleUrl}/eggs";

            return($"{url}/{raid.Level}.png");
        }
Exemplo n.º 2
0
        private void ParseRaid(dynamic message)
        {
            try
            {
                RaidData raid = JsonConvert.DeserializeObject <RaidData>(Convert.ToString(message));
                if (raid == null)
                {
                    _logger.Error($"Failed to parse Pokemon webhook object: {message}");
                    return;
                }

                if (SkipEggs && raid.PokemonId == 0)
                {
                    _logger.Debug($"Level {raid.Level} Egg, skipping...");
                    return;
                }

                raid.SetTimes();

                OnRaidReceived(raid);
            }
            catch (Exception ex)
            {
                _logger.Error(ex.StackTrace);
                _logger.Debug(Convert.ToString(message));
            }
        }
Exemplo n.º 3
0
 public EpgpRaidMonitor(IEmoteService emoteService, RaidData raidData, IServiceScopeFactory serviceScopeFactory)
 {
     _emoteService        = emoteService;
     _raidData            = raidData;
     _serviceScopeFactory = serviceScopeFactory;
     _cts = new CancellationTokenSource();
     _raidData.RaidObject.PropertyChanged += RaidPropertyChanged;
 }
Exemplo n.º 4
0
 public ScannedRaid(RaidData raid)
 {
     Latitude   = raid.Latitude;
     Longitude  = raid.Longitude;
     Level      = raid.Level;
     PokemonId  = raid.PokemonId;
     FormId     = raid.Form;
     CostumeId  = raid.Costume;
     ExpireTime = raid.EndTime;
 }
Exemplo n.º 5
0
        private void ParseRaid(dynamic message)
        {
            try
            {
                RaidData raid = JsonConvert.DeserializeObject <RaidData>(Convert.ToString(message));
                if (raid == null)
                {
                    _logger.Error($"Failed to parse Pokemon webhook object: {message}");
                    return;
                }

                /*
                 * if (SkipEggs && raid.PokemonId == 0)
                 * {
                 *  _logger.Debug($"Level {raid.Level} Egg, skipping...");
                 *  return;
                 * }
                 */

                raid.SetTimes();

                if (_checkForDuplicates)
                {
                    lock (_processedRaids)
                    {
                        if (_processedRaids.ContainsKey(raid.GymId))
                        {
                            if (_processedRaids[raid.GymId].PokemonId == raid.PokemonId &&
                                _processedRaids[raid.GymId].FormId == raid.Form &&
                                _processedRaids[raid.GymId].CostumeId == raid.Costume &&
                                _processedRaids[raid.GymId].Level == raid.Level &&
                                !_processedRaids[raid.GymId].IsExpired)
                            {
                                // Processed raid already
                                return;
                            }

                            _processedRaids[raid.GymId] = new ScannedRaid(raid);
                        }
                        else
                        {
                            _processedRaids.Add(raid.GymId, new ScannedRaid(raid));
                        }
                    }
                }

                OnRaidReceived(raid);
            }
            catch (Exception ex)
            {
                _logger.Error(ex.StackTrace);
                _logger.Debug(Convert.ToString(message));
            }
        }
Exemplo n.º 6
0
        private void OnRaidSubscriptionTriggered(object sender, RaidData e)
        {
            if (_subProcessor == null)
            {
                return;
            }

            if (!ThreadPool.QueueUserWorkItem(async x => await _subProcessor.ProcessRaidSubscription(e)))
            {
                // Failed to queue thread
                _logger.Error($"Failed to queue thread to process raid subscription");
            }
        }
Exemplo n.º 7
0
        private void ParseRaid(dynamic message)
        {
            try
            {
                RaidData raid = JsonConvert.DeserializeObject <RaidData>(Convert.ToString(message));
                if (raid == null)
                {
                    _logger.Error($"Failed to parse Pokemon webhook object: {message}");
                    return;
                }

                if (SkipEggs && raid.PokemonId == 0)
                {
                    _logger.Debug($"Level {raid.Level} Egg, skipping...");
                    return;
                }

                raid.SetTimes();

                lock (_processedRaids)
                {
                    if (_processedRaids.ContainsKey(raid.GymId))
                    {
                        /*
                         * if ((_processedRaids[raid.GymId].PokemonId == 0 || _processedRaids[raid.GymId].PokemonId == raid.PokemonId) &&
                         *  _processedRaids[raid.GymId].Form == raid.Form &&
                         *  _processedRaids[raid.GymId].Level == raid.Level &&
                         *  _processedRaids[raid.GymId].Start == raid.Start &&
                         *  _processedRaids[raid.GymId].End == raid.End)
                         * {
                         *  _logger.Debug($"PROCESSED RAID ALREADY: Id: {raid.GymId} Name: {raid.GymName} Pokemon: {raid.PokemonId} Form: {raid.Form} Start: {raid.StartTime} End: {raid.EndTime}");
                         *  // Processed raid already
                         *  return;
                         * }
                         */
                    }
                    else
                    {
                        _processedRaids.Add(raid.GymId, raid);
                    }
                }

                OnRaidReceived(raid);
            }
            catch (Exception ex)
            {
                _logger.Error(ex.StackTrace);
                _logger.Debug(Convert.ToString(message));
            }
        }
Exemplo n.º 8
0
        private void OnRaidSubscriptionTriggered(object sender, RaidData e)
        {
            if (!_whConfig.Discord.EnableSubscriptions)
            {
                return;
            }

            if (_subProcessor == null)
            {
                return;
            }

            new System.Threading.Thread(async() => await _subProcessor.ProcessRaidSubscription(e))
            {
                IsBackground = true
            }.Start();
        }
Exemplo n.º 9
0
        public async Task ProcessRaid(RaidData raid)
        {
            if (raid == null)
            {
                return;
            }

            if (_db == null)
            {
                _logger.Error($"Database is not initialized...");
                return;
            }

            DiscordUser            discordUser;
            Subscription <Pokemon> user;
            Pokemon      subscribedRaid;
            DiscordEmbed embed;

            for (int i = 0; i < _db.Subscriptions.Count; i++)
            {
                try
                {
                    user = _db.Subscriptions[i];
                    if (user == null)
                    {
                        continue;
                    }
                    if (!user.Enabled)
                    {
                        continue;
                    }

                    discordUser = await _client.GetUser(user.UserId);

                    if (discordUser == null)
                    {
                        if (!_db.Subscriptions.Remove(user))
                        {
                            _logger.Error($"Failed to remove non-existing user {user.UserId} from database.");
                        }
                        continue;
                    }

                    if (!user.Raids.Exists(x => x.PokemonId == raid.PokemonId))
                    {
                        continue;
                    }
                    subscribedRaid = user.Raids.Find(x => x.PokemonId == raid.PokemonId);
                    if (subscribedRaid == null)
                    {
                        continue;
                    }

                    //if (!_db.Pokemon.ContainsKey(subscribedRaid.PokemonId.ToString())) continue;
                    //var pokemon = _db.Pokemon[subscribedRaid.PokemonId.ToString()];
                    //if (pokemon == null) continue;

                    if (_client == null)
                    {
                        continue;
                    }
                    //if (!await _client.IsSupporterOrHigher(user.UserId, _config)) continue;

                    if (subscribedRaid.PokemonId != raid.PokemonId)
                    {
                        continue;
                    }

                    if (user.NotificationLimiter.IsLimited())
                    {
                        if (!user.NotifiedOfLimited)
                        {
                            await _client.SendDirectMessage(discordUser, string.Format(NotificationsLimitedMessage, NotificationLimiter.MaxNotificationsPerMinute), null);

                            user.NotifiedOfLimited = true;
                        }

                        continue;
                    }

                    user.NotifiedOfLimited = false;

                    _logger.Info($"Notifying user {discordUser.Username} that a {raid.PokemonId} raid is available...");

                    embed = await _builder.BuildRaidMessage(raid, user.UserId);

                    if (embed == null)
                    {
                        continue;
                    }

                    //if (await CheckIfExceededNotificationLimit(user)) return;

                    user.NotificationsToday++;

                    await SendNotification(discordUser, raid.PokemonId.ToString(), embed);
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                }
            }
        }
Exemplo n.º 10
0
 public void AddOrUpdateRaid(RaidData raidData)
 {
     _raids.AddOrUpdate(raidData.Id, id => raidData, (id, data) => raidData);
 }
Exemplo n.º 11
0
 public EpgpRaidMonitor GetNew(RaidData raidData)
 {
     return(new EpgpRaidMonitor(_emoteService, raidData, _serviceScopeFactory));
 }
Exemplo n.º 12
0
        public async Task ProcessRaidSubscription(RaidData raid)
        {
            if (!MasterFile.Instance.Pokedex.ContainsKey(raid.PokemonId))
            {
                return;
            }

            var loc = _whm.GetGeofence(raid.Latitude, raid.Longitude);

            if (loc == null)
            {
                //_logger.Warn($"Failed to lookup city for coordinates {raid.Latitude},{raid.Longitude}, skipping...");
                return;
            }

            var subscriptions = Manager.GetUserSubscriptionsByRaidBossId(raid.PokemonId);

            if (subscriptions == null)
            {
                _logger.Warn($"Failed to get subscriptions from database table.");
                return;
            }

            SubscriptionObject user;
            var pokemon = MasterFile.GetPokemon(raid.PokemonId, raid.Form);

            for (int 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];

                    var member = await client.GetMemberById(user.GuildId, user.UserId);

                    if (member == null)
                    {
                        _logger.Warn($"Failed to find member with id {user.UserId}.");
                        continue;
                    }

                    if (!member.HasSupporterRole(_whConfig.Servers[user.GuildId].DonorRoleIds))
                    {
                        _logger.Info($"User {user.UserId} is not a supporter, skipping raid boss {pokemon.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(raid.Latitude, raid.Longitude));
                        if (user.DistanceM < distance)
                        {
                            //Skip if distance is set and is not met.
                            _logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid is farther than set distance of '{user.DistanceM} meters.");
                            continue;
                        }
                    }

                    if (user.Gyms.Count > 0 && (!user.Gyms?.Exists(x =>
                                                                   !string.IsNullOrEmpty(x?.Name) &&
                                                                   (
                                                                       (raid.GymName?.ToLower()?.Contains(x.Name?.ToLower()) ?? false) ||
                                                                       (raid.GymName?.ToLower()?.StartsWith(x.Name?.ToLower()) ?? false)
                                                                   )
                                                                   ) ?? false))
                    {
                        //Skip if list is not empty and gym is not in list.
                        _logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid '{raid.GymName}' is not in list of subscribed gyms.");
                        continue;
                    }

                    var form   = Translator.Instance.GetFormName(raid.Form);
                    var exists = user.Raids.FirstOrDefault(x =>
                                                           x.PokemonId == raid.PokemonId &&
                                                           (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))
                                                           ) != null;
                    if (!exists)
                    {
                        //_logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid is in city '{loc.Name}'.");
                        continue;
                    }

                    var embed = raid.GenerateRaidMessage(user.GuildId, client, _whConfig, null, loc.Name);
                    foreach (var emb in embed.Embeds)
                    {
                        _queue.Enqueue(new NotificationItem(user, member, emb, pokemon.Name, loc.Name));
                    }

                    Statistics.Instance.SubscriptionRaidsSent++;
                    Thread.Sleep(5);
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                }
            }

            subscriptions.Clear();
            subscriptions = null;
            user          = null;
            loc           = null;

            await Task.CompletedTask;
        }
Exemplo n.º 13
0
        public async Task ProcessGymSubscription(RaidData raid)
        {
            //if (!MasterFile.Instance.Pokedex.ContainsKey(raid.PokemonId))
            //    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, raid.Latitude, raid.Longitude);
                    locationCache.Add(guildId, geofence);
                }

                return(geofence);
            }

            var subscriptions = Manager.GetUserSubscriptionsByGymName(raid.GymName);

            if (subscriptions == null)
            {
                _logger.Warn($"Failed to get subscriptions from database table.");
                return;
            }

            SubscriptionObject user;
            var pokemon = MasterFile.GetPokemon(raid.PokemonId, raid.Form);

            for (int 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];

                    var member = await client.GetMemberById(user.GuildId, user.UserId);

                    if (member == null)
                    {
                        _logger.Warn($"Failed to find member with id {user.UserId}.");
                        continue;
                    }

                    if (!member.HasSupporterRole(_whConfig.Instance.Servers[user.GuildId].DonorRoleIds))
                    {
                        _logger.Info($"User {user.UserId} is not a supporter, skipping raid boss {pokemon.Name} for gym {raid.GymName}...");
                        // Automatically disable users subscriptions if not supporter to prevent issues
                        //user.Enabled = false;
                        //user.Save(false);
                        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 gymSub = user.Gyms.FirstOrDefault(x => string.Compare(x.Name, raid.GymName, true) == 0);
                    if (gymSub == null)
                    {
                        continue;
                    }

                    var checkLevel      = gymSub.MinimumLevel > 0 && gymSub.MaximumLevel > 0;
                    var containsPokemon = gymSub.PokemonIDs?.Contains((uint)raid.PokemonId) ?? false;
                    if (!checkLevel && !containsPokemon)
                    {
                        continue;
                    }

                    var embed = raid.GenerateRaidMessage(user.GuildId, client, _whConfig.Instance, null, geofence.Name);
                    //var end = DateTime.Now;
                    //_logger.Debug($"Took {end} to process gym raid subscription for user {user.UserId}");
                    embed.Embeds.ForEach(x => _queue.Enqueue(new NotificationItem(user, member, x, pokemon.Name, geofence.Name)));

                    Statistics.Instance.SubscriptionRaidsSent++;
                    Thread.Sleep(5);
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                }
            }

            subscriptions.Clear();
            subscriptions = null;
            user          = null;

            await Task.CompletedTask;
        }
Exemplo n.º 14
0
        public async Task ProcessRaidSubscription(RaidData raid)
        {
            if (!_whConfig.Discord.EnableSubscriptions)
            {
                return;
            }

            var db = Database.Instance;

            if (!db.Pokemon.ContainsKey(raid.PokemonId))
            {
                return;
            }

            var loc = _whm.GetGeofence(raid.Latitude, raid.Longitude);

            if (loc == null)
            {
                //_logger.Warn($"Failed to lookup city for coordinates {raid.Latitude},{raid.Longitude}, skipping...");
                return;
            }

            var subscriptions = Manager.GetUserSubscriptionsByRaidBossId(raid.PokemonId);

            if (subscriptions == null)
            {
                _logger.Warn($"Failed to get subscriptions from database table.");
                return;
            }

            SubscriptionObject user;
            var pokemon = db.Pokemon[raid.PokemonId];

            for (int i = 0; i < subscriptions.Count; i++)
            {
                try
                {
                    user = subscriptions[i];
                    if (user == null)
                    {
                        continue;
                    }

                    if (!user.Enabled)
                    {
                        continue;
                    }

                    var member = await _client.GetMemberById(_whConfig.Discord.GuildId, user.UserId);

                    if (member == null)
                    {
                        _logger.Warn($"Failed to find member with id {user.UserId}.");
                        continue;
                    }

                    if (!member.HasSupporterRole(_whConfig.Discord.DonorRoleIds))
                    {
                        _logger.Info($"User {user.UserId} is not a supporter, skipping raid boss {pokemon.Name}...");
                        continue;
                    }

                    //if (!member.Roles.Select(x => x.Name.ToLower()).Contains(loc.Name.ToLower()))
                    //{
                    //    _logger.Debug($"[{loc.Name}] Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name} because they do not have the city role '{loc.Name}'.");
                    //    continue;
                    //}

                    if (user.DistanceM > 0)
                    {
                        var distance = new Coordinates(user.Latitude, user.Longitude).DistanceTo(new Coordinates(raid.Latitude, raid.Longitude));
                        if (user.DistanceM < distance)
                        {
                            //Skip if distance is set and is not met.
                            _logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid is farther than set distance of '{user.DistanceM} meters.");
                            continue;
                        }
                    }

                    if (user.Gyms.Count > 0 && !user.Gyms.Exists(x => !string.IsNullOrEmpty(x?.Name) && raid.GymName.ToLower().Contains(x.Name?.ToLower())))
                    {
                        //Skip if list is not empty and gym is not in list.
                        _logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid '{raid.GymName}' is not in list of subscribed gyms.");
                        continue;
                    }

                    var form   = raid.PokemonId.GetPokemonForm(raid.Form.ToString());
                    var exists = user.Raids.FirstOrDefault(x =>
                                                           x.PokemonId == raid.PokemonId &&
                                                           //(string.Compare(x.Form, form, true) == 0 || string.IsNullOrEmpty(x.Form)) &&
                                                           (x.Form == null || x.Form == string.Empty || string.Compare(x.Form, form, true) == 0) &&
                                                           //string.Compare(x.Form, form, true) == 0 &&
                                                           (string.IsNullOrEmpty(x.City) || (!string.IsNullOrEmpty(x.City) && string.Compare(loc.Name, x.City, true) == 0))
                                                           ) != null;
                    if (!exists)
                    {
                        //_logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid is in city '{loc.Name}'.");
                        continue;
                    }

                    //_logger.Debug($"Notifying user {member.Username} that a {raid.PokemonId} raid is available...");

                    var iconStyle = Manager.GetUserIconStyle(user);
                    var embed     = raid.GenerateRaidMessage(_client, _whConfig, null, loc.Name, string.Format(_whConfig.IconStyles[iconStyle], raid.PokemonId, raid.Form));
                    _queue.Enqueue(new Tuple <DiscordUser, string, DiscordEmbed>(member, pokemon.Name, embed));

                    //if (!Manager.AddRaidStatistic(member.Id, raid))
                    //{
                    //    _logger.Warn($"Failed to add {pokemon.Name} raid statistic for user {user.Id}.");
                    //}
                    Statistics.Instance.SubscriptionRaidsSent++;
                    Thread.Sleep(5);
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                }
            }

            subscriptions.Clear();
            subscriptions = null;
            user          = null;
            loc           = null;
            db            = null;

            await Task.CompletedTask;
        }
Exemplo n.º 15
0
        private void ProcessRaid(RaidData raid)
        {
            if (raid == null)
            {
                return;
            }

            if (raid.IsEgg)
            {
                Statistics.Instance.TotalReceivedEggs++;
            }
            else
            {
                Statistics.Instance.TotalReceivedRaids++;
            }

            foreach (var(guildId, alarms) in _alarms)
            {
                if (!alarms.EnableRaids)
                {
                    continue;
                }

                if (alarms.Alarms?.Count == 0)
                {
                    continue;
                }

                var raidAlarms = alarms.Alarms.FindAll(x => x.Filters?.Raids?.Pokemon != null);
                for (var j = 0; j < raidAlarms.Count; j++)
                {
                    var alarm    = raidAlarms[j];
                    var geofence = GeofenceService.GetGeofence(alarm.GeofenceItems, new Location(raid.Latitude, raid.Longitude));
                    if (geofence == null)
                    {
                        //_logger.Info($"[{alarm.Name}] Skipping raid Pokemon={raid.PokemonId}, Level={raid.Level}: not in geofence.");
                        continue;
                    }

                    if (raid.IsEgg)
                    {
                        if (alarm.Filters.Eggs == null)
                        {
                            continue;
                        }

                        if (!alarm.Filters.Eggs.Enabled)
                        {
                            //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: raids filter not enabled.");
                            continue;
                        }

                        if (!int.TryParse(raid.Level, out var level))
                        {
                            _logger.Warn($"[{alarm.Name}] [{geofence.Name}] Failed to parse '{raid.Level}' as raid level.");
                            continue;
                        }

                        if (!(level >= alarm.Filters.Eggs.MinimumLevel && level <= alarm.Filters.Eggs.MaximumLevel))
                        {
                            //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: '{raid.Level}' does not meet the MinimumLevel={alarm.Filters.Eggs.MinimumLevel} and MaximumLevel={alarm.Filters.Eggs.MaximumLevel} filters.");
                            continue;
                        }

                        if (alarm.Filters.Eggs.OnlyEx && !raid.IsExEligible)
                        {
                            //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: only ex {alarm.Filters.Eggs.OnlyEx}.");
                            continue;
                        }

                        if (alarm.Filters.Eggs.Team != PokemonTeam.All && alarm.Filters.Eggs.Team != raid.Team)
                        {
                            //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: '{raid.Team}' does not meet Team={alarm.Filters.Eggs.Team} filter.");
                            continue;
                        }

                        OnRaidAlarmTriggered(raid, alarm, guildId);
                    }
                    else
                    {
                        if (alarm.Filters.Raids == null)
                        {
                            continue;
                        }

                        if (!alarm.Filters.Raids.Enabled)
                        {
                            //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: raids filter not enabled.");
                            continue;
                        }

                        if (!int.TryParse(raid.Level, out var level))
                        {
                            _logger.Warn($"[{alarm.Name}] [{geofence.Name}] Failed to parse '{raid.Level}' as raid level.");
                            continue;
                        }

                        if (!(level >= alarm.Filters.Raids.MinimumLevel && level <= alarm.Filters.Raids.MaximumLevel))
                        {
                            //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid {raid.PokemonId}: '{raid.Level}' does not meet the MinimumLevel={alarm.Filters.Raids.MinimumLevel} and MaximumLevel={alarm.Filters.Raids.MaximumLevel} filters.");
                            continue;
                        }

                        if (alarm.Filters.Raids.FilterType == FilterType.Exclude && alarm.Filters.Raids.Pokemon.Contains(raid.PokemonId))
                        {
                            //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: filter {alarm.Filters.Raids.FilterType}.");
                            continue;
                        }

                        if (alarm.Filters.Raids.FilterType == FilterType.Include && (!alarm.Filters.Raids.Pokemon.Contains(raid.PokemonId) && alarm.Filters.Raids.Pokemon?.Count > 0))
                        {
                            //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: filter {alarm.Filters.Raids.FilterType}.");
                            continue;
                        }

                        if (alarm.Filters.Raids.OnlyEx && !raid.IsExEligible)
                        {
                            //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: only ex {alarm.Filters.Raids.OnlyEx}.");
                            continue;
                        }

                        if (alarm.Filters.Raids.Team != PokemonTeam.All && alarm.Filters.Raids.Team != raid.Team)
                        {
                            //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: '{raid.Team}' does not meet Team={alarm.Filters.Raids.Team} filter.");
                            continue;
                        }

                        if (alarm.Filters.Raids.IgnoreMissing && raid.IsMissingStats)
                        {
                            _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: IgnoreMissing=true.");
                            continue;
                        }

                        OnRaidAlarmTriggered(raid, alarm, guildId);
                    }
                }
            }
        }
Exemplo n.º 16
0
        private void ProcessRaid(RaidData raid)
        {
            if (!_alarms.EnableRaids)
            {
                return;
            }

            if (raid == null)
            {
                return;
            }

            if (_alarms.Alarms?.Count == 0)
            {
                return;
            }

            for (var i = 0; i < _alarms.Alarms.Count; i++)
            {
                var alarm    = _alarms.Alarms[i];
                var geofence = InGeofence(alarm.Geofences, new Location(raid.Latitude, raid.Longitude));
                if (geofence == null)
                {
                    //_logger.Info($"[{alarm.Name}] Skipping raid Pokemon={raid.PokemonId}, Level={raid.Level} because not in geofence.");
                    continue;
                }

                if (raid.IsEgg)
                {
                    if (alarm.Filters.Eggs == null)
                    {
                        continue;
                    }

                    if (!alarm.Filters.Eggs.Enabled)
                    {
                        _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: raids filter not enabled.");
                        continue;
                    }

                    if (!int.TryParse(raid.Level, out var level))
                    {
                        _logger.Warn($"[{alarm.Name}] [{geofence.Name}] Failed to parse '{raid.Level}' as raid level.");
                        continue;
                    }

                    if (!(level >= alarm.Filters.Eggs.MinimumLevel && level <= alarm.Filters.Eggs.MaximumLevel))
                    {
                        //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: '{raid.Level}' does not meet the MinimumLevel={alarm.Filters.Eggs.MinimumLevel} and MaximumLevel={alarm.Filters.Eggs.MaximumLevel} filters.");
                        continue;
                    }

                    if (alarm.Filters.Eggs.OnlyEx && !raid.IsExEligible)
                    {
                        //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: only ex {alarm.Filters.Eggs.OnlyEx}.");
                        continue;
                    }

                    if (alarm.Filters.Eggs.Team != PokemonTeam.All && alarm.Filters.Eggs.Team != raid.Team)
                    {
                        //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: '{raid.Team}' does not meet Team={alarm.Filters.Eggs.Team} filter.");
                        continue;
                    }

                    OnRaidAlarmTriggered(raid, alarm);
                }
                else
                {
                    if (alarm.Filters.Raids == null)
                    {
                        continue;
                    }

                    if (!alarm.Filters.Raids.Enabled)
                    {
                        _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: raids filter not enabled.");
                        continue;
                    }

                    if (alarm.Filters.Raids.FilterType == FilterType.Exclude && alarm.Filters.Raids.Pokemon.Contains(raid.PokemonId))
                    {
                        _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: filter {alarm.Filters.Raids.FilterType}.");
                        continue;
                    }

                    if (alarm.Filters.Raids.FilterType == FilterType.Include && (!alarm.Filters.Raids.Pokemon.Contains(raid.PokemonId) && alarm.Filters.Raids.Pokemon?.Count > 0))
                    {
                        _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: filter {alarm.Filters.Raids.FilterType}.");
                        continue;
                    }

                    if (alarm.Filters.Raids.OnlyEx && !raid.IsExEligible)
                    {
                        _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: only ex {alarm.Filters.Raids.OnlyEx}.");
                        continue;
                    }

                    if (alarm.Filters.Raids.Team != PokemonTeam.All && alarm.Filters.Raids.Team != raid.Team)
                    {
                        _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: '{raid.Team}' does not meet Team={alarm.Filters.Raids.Team} filter.");
                        continue;
                    }

                    if (alarm.Filters.Raids.IgnoreMissing && raid.IsMissingStats)
                    {
                        _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: IgnoreMissing=true.");
                        continue;
                    }

                    OnRaidAlarmTriggered(raid, alarm);
                }
            }
        }
Exemplo n.º 17
0
 public RaidDataEventArgs(RaidData raid)
 {
     Raid = raid;
 }
Exemplo n.º 18
0
 public void Dispose()
 {
     _raidData.RaidObject.PropertyChanged -= RaidPropertyChanged;
     _cts?.Dispose();
     _raidData = null;
 }
Exemplo n.º 19
0
 private void OnRaidReceived(RaidData raid) => RaidReceived?.Invoke(this, new DataReceivedEventArgs <RaidData>(raid));
Exemplo n.º 20
0
        public async Task <DiscordEmbed> BuildRaidMessage(RaidData raid, ulong userId)
        {
            var pkmn = _db.Pokemon[raid.PokemonId.ToString()];

            if (pkmn == null)
            {
                _logger.Error($"Failed to lookup Raid Pokemon '{raid.PokemonId}' in database.");
                return(null);
            }

            var user = await _client.GetMemberFromUserId(userId);

            if (user == null)
            {
                _logger.Error($"Failed to get discord member object from user id {userId}.");
                return(null);
            }

            //var loc = Utils.GetGoogleAddress(raid.Latitude, raid.Longitude, _config.GmapsKey);
            var loc = _geofenceSvc.GetGeofence(new Location(raid.Latitude, raid.Longitude));

            if (loc == null)
            {
                _logger.Error($"Failed to lookup city for coordinates {raid.Latitude},{raid.Longitude}, skipping...");
                return(null);
            }

            if (!_config.CityRoles.Exists(x => string.Compare(x, loc.Name, true) == 0))
            {
                File.AppendAllText("cities.txt", $"City: {loc.Name}\r\n");
            }

            if (!_client.HasRole(user, loc.Name))
            {
                _logger.Debug($"Skipping notification for user {user.DisplayName} ({user.Id}) for Pokemon {pkmn.Name} because they do not have the city role '{loc.Name}'.");
                return(null);
            }

            var eb = new DiscordEmbedBuilder
            {
                Title = loc == null || string.IsNullOrEmpty(loc.Name) ? "DIRECTIONS" : loc.Name,
                //Description = $"{pkmn.Name} raid available until {raid.EndTime.ToLongTimeString()}!",
                Url          = string.Format(Strings.GoogleMaps, raid.Latitude, raid.Longitude),
                ImageUrl     = string.Format(Strings.GoogleMapsStaticImage, raid.Latitude, raid.Longitude),
                ThumbnailUrl = string.Format(Strings.PokemonImage, raid.PokemonId, 0),
                Color        = DiscordHelpers.BuildRaidColor(Convert.ToInt32(raid.Level))
            };

            var fixedEndTime = DateTime.Parse(raid.EndTime.ToLongTimeString());
            var remaining    = GetTimeRemaining(fixedEndTime);

            eb.Description  = $"{pkmn.Name} Raid Ends: {raid.EndTime.ToLongTimeString()}\r\n\r\n";
            eb.Description += $"**Starts:** {raid.StartTime.ToLongTimeString()}\r\n";
            eb.Description += $"**Ends:** {raid.EndTime.ToLongTimeString()} ({remaining.ToReadableStringNoSeconds()} left)\r\n";

            var perfectRange = _db.GetPokemonCpRange(raid.PokemonId, 20);
            var boostedRange = _db.GetPokemonCpRange(raid.PokemonId, 25);

            eb.Description += $"**Perfect CP:** {perfectRange.Best} / :white_sun_rain_cloud: {boostedRange.Best}\r\n";

            if (pkmn.Types.Count > 0)
            {
                var types = new List <string>();
                pkmn.Types.ForEach(x =>
                {
                    if (Strings.TypeEmojis.ContainsKey(x.Type.ToLower()))
                    {
                        types.Add(Strings.TypeEmojis[x.Type.ToLower()] + " " + x.Type);
                    }
                });
                eb.Description += $"**Types:** {string.Join("/", types)}\r\n";
            }

            var fastMove = _db.Movesets.ContainsKey(raid.FastMove) ? _db.Movesets[raid.FastMove] : null;

            if (fastMove != null)
            {
                eb.Description += $"**Fast Move:** {Strings.TypeEmojis[fastMove.Type.ToLower()]} {fastMove.Name}\r\n";
            }

            var chargeMove = _db.Movesets.ContainsKey(raid.ChargeMove) ? _db.Movesets[raid.ChargeMove] : null;

            if (chargeMove != null)
            {
                eb.Description += $"**Charge Move:** {Strings.TypeEmojis[chargeMove.Type.ToLower()]} {chargeMove.Name}\r\n";
            }

            var strengths  = new List <string>();
            var weaknesses = new List <string>();

            foreach (var type in pkmn.Types)
            {
                foreach (var strength in PokemonExtensions.GetStrengths(type.Type))
                {
                    if (!strengths.Contains(strength))
                    {
                        strengths.Add(strength);
                    }
                }
                foreach (var weakness in PokemonExtensions.GetWeaknesses(type.Type))
                {
                    if (!weaknesses.Contains(weakness))
                    {
                        weaknesses.Add(weakness);
                    }
                }
            }

            if (strengths.Count > 0)
            {
                eb.Description += $"**Strong Against:** {string.Join(", ", strengths)}\r\n";
            }

            if (weaknesses.Count > 0)
            {
                eb.Description += $"**Weaknesses:** {string.Join(", ", weaknesses)}\r\n";
            }

            eb.Description += $"**Location:** {Math.Round(raid.Latitude, 5)},{Math.Round(raid.Longitude, 5)}";
            eb.ImageUrl     = string.Format(Strings.GoogleMapsStaticImage, raid.Latitude, raid.Longitude) + $"&key={_config.GmapsKey}";
            eb.Footer       = new DiscordEmbedBuilder.EmbedFooter
            {
                Text = $"versx | {DateTime.Now}"
            };
            var embed = eb.Build();

            return(embed);
        }
Exemplo n.º 21
0
 private void OnRaidSubscriptionTriggered(RaidData raid)
 {
     RaidSubscriptionTriggered?.Invoke(this, raid);
 }
Exemplo n.º 22
0
        public async Task ProcessRaidSubscription(RaidData raid)
        {
            if (!MasterFile.Instance.Pokedex.ContainsKey(raid.PokemonId))
            {
                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, raid.Latitude, raid.Longitude);
                    locationCache.Add(guildId, geofence);
                }

                return(geofence);
            }

            var subscriptions = Manager.GetUserSubscriptionsByRaidBossId(raid.PokemonId);

            if (subscriptions == null)
            {
                _logger.Warn($"Failed to get subscriptions from database table.");
                return;
            }

            SubscriptionObject user;
            var pokemon = MasterFile.GetPokemon(raid.PokemonId, raid.Form);

            for (int 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];

                    var member = await client.GetMemberById(user.GuildId, user.UserId);

                    if (member == null)
                    {
                        _logger.Warn($"Failed to find member with id {user.UserId}.");
                        continue;
                    }

                    if (!member.HasSupporterRole(_whConfig.Instance.Servers[user.GuildId].DonorRoleIds))
                    {
                        _logger.Info($"User {user.UserId} is not a supporter, skipping raid boss {pokemon.Name}...");
                        // Automatically disable users subscriptions if not supporter to prevent issues
                        //user.Enabled = false;
                        //user.Save(false);
                        continue;
                    }

                    var form    = Translator.Instance.GetFormName(raid.Form);
                    var subPkmn = user.Raids.FirstOrDefault(x =>
                                                            x.PokemonId == raid.PokemonId &&
                                                            (string.IsNullOrEmpty(x.Form) || (!string.IsNullOrEmpty(x.Form) && string.Compare(x.Form, form, true) == 0))
                                                            );
                    // Not subscribed to Pokemon
                    if (subPkmn == null)
                    {
                        //_logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid is in city '{loc.Name}'.");
                        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(raid.Latitude, raid.Longitude));
                    var geofenceMatches = subPkmn.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 = raid.GenerateRaidMessage(user.GuildId, client, _whConfig.Instance, null, geofence.Name);
                    //var end = DateTime.Now;
                    //_logger.Debug($"Took {end} to process raid subscription for user {user.UserId}");
                    embed.Embeds.ForEach(x => _queue.Enqueue(new NotificationItem(user, member, x, pokemon.Name, geofence.Name)));

                    Statistics.Instance.SubscriptionRaidsSent++;
                    Thread.Sleep(5);
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                }
            }

            subscriptions.Clear();
            subscriptions = null;
            user          = null;

            await Task.CompletedTask;
        }
Exemplo n.º 23
0
 private void OnRaidAlarmTriggered(RaidData raid, AlarmObject alarm, ulong guildId)
 {
     RaidAlarmTriggered?.Invoke(this, new AlarmEventTriggeredEventArgs <RaidData>(raid, alarm, guildId));
 }
Exemplo n.º 24
0
        public static async Task Initialize() => await Task.Run(() =>
        {
            DiscordShardedClient client = ConfigProperties.Client;
            client.UserJoined          += async u =>
            {
                SocketGuild guild = u.Guild;
                Server server     = await DatabaseQueries.GetOrCreateServerAsync(guild.Id);

                if (server.AntiRaid == null)
                {
                    return;
                }

                AntiRaidConfig ar = server.AntiRaid;

                if (!ActiveAntiraids.Raids.Any(x => x.ServerId == server.ServerId))
                {
                    var newRaidData = new RaidData
                    {
                        ServerId = server.ServerId,
                        UserIds  = new HashSet <ulong>
                        {
                            u.Id
                        }
                    };

                    ActiveAntiraids.SafeAdd(newRaidData);
                }
                else
                {
                    var newIds = new HashSet <ulong>();
                    HashSet <ulong> existingIds = ActiveAntiraids.Raids.First(x => x.ServerId == server.ServerId).UserIds;

                    // Copies existing IDs from the known / active raid into a new HashSet<ulong>.
                    foreach (ulong id in existingIds)
                    {
                        newIds.Add(id);
                    }

                    // Finally, add the current user's ID to the HashSet.
                    newIds.Add(u.Id);

                    // Replace the object in memory.
                    ActiveAntiraids.ReplaceRaidData(new RaidData
                    {
                        ServerId = server.ServerId,
                        UserIds  = newIds
                    });
                }

                var timer       = new Timer(ar.Seconds * 1000);
                timer.Enabled   = true;
                timer.AutoReset = false;
                timer.Elapsed  += async(sender, args) =>
                {
                    RaidData existingObj = ActiveAntiraids.Raids.FirstOrDefault(x => x.ServerId == server.ServerId);

                    if (existingObj == null)
                    {
                        return;
                    }

                    // Filter by distinct to fix the duplicate users issue.
                    existingObj.UserIds = existingObj.UserIds.Distinct().ToHashSet();

                    // This must be above ActionUsers() as it takes a few seconds for users to be actioned
                    // resulting in duplicate log messages and ban attempts.
                    ActiveAntiraids.RemoveAll(existingObj);
                    if (existingObj.UserIds.Count >= ar.Users)
                    {
                        await ActionUsers(existingObj.UserIds, server.ServerId, ar.Action);
                    }
                };
            };
        });