Example #1
0
        public void Start()
        {
            _logger.Trace("Start");
            _logger.Info("Connecting to Discord...");

            _client.ConnectAsync();
        }
Example #2
0
        public async Task StartAsync()
        {
            _logger.Trace($"FilterBot::Start");

            if (_client == null)
            {
                _logger.Error($"Really don't know how this happened?");
                return;
            }

            var http = new HttpServer(_config, _logger);

            http.PokemonReceived += PokemonReceived;
            http.RaidReceived    += RaidReceived;

            if (_timer == null)
            {
                _timer          = new Timer(1000 * 60 * 15);
                _timer.Elapsed += MinuteTimerEventHandler;
                _timer.Start();
            }

            _logger.Info("Connecting to discord server...");

            await Utils.Wait(500);

            await _client.ConnectAsync();
        }
Example #3
0
        private void LoadGeofences()
        {
            foreach (var(serverId, serverConfig) in _config.Instance.Servers)
            {
                serverConfig.Geofences.Clear();

                var geofenceFiles = serverConfig.GeofenceFiles;
                var geofences     = new List <GeofenceItem>();

                if (geofenceFiles != null && geofenceFiles.Any())
                {
                    foreach (var file in geofenceFiles)
                    {
                        var filePath = Path.Combine(Strings.GeofenceFolder, file);

                        try
                        {
                            var fileGeofences = GeofenceItem.FromFile(filePath);

                            geofences.AddRange(fileGeofences);

                            _logger.Info($"Successfully loaded {fileGeofences.Count} geofences from {file}");
                        }
                        catch (Exception ex)
                        {
                            _logger.Error($"Could not load Geofence file {file} (for server {serverId}):");
                            _logger.Error(ex);
                        }
                    }
                }

                serverConfig.Geofences.AddRange(geofences);
            }
        }
Example #4
0
        private void AssignGuildMembersToRole(DiscordMessage message, List <string> roles, bool defaultCityFeed)
        {
#pragma warning disable RECS0165
            new System.Threading.Thread(async x =>
#pragma warning restore RECS0165
            {
                var guild   = message.Channel.Guild;
                var success = 0;
                var errors  = 0;
                var failed  = new List <string>();

                await message.RespondAsync
                (
                    defaultCityFeed
                    ? $"Starting default city feed assignment for all users of guild **{guild.Name}**."
                    : $"Starting {string.Join(",", roles)} role(s) assignment to all users of guild **{guild.Name}**."
                );

                foreach (var member in guild.Members)
                {
                    try
                    {
                        foreach (var role in roles)
                        {
                            var discordRole = _client.GetRoleFromName(role);
                            if (discordRole == null)
                            {
                                //Failed to find role.
                                _logger.Error($"Failed to find city role {role}, please make sure it exists.");
                                continue;
                            }

                            await member.GrantRoleAsync(discordRole, $"{discordRole.Name} role assignment.");
                            _logger.Info($"Assigned {member.Username} to role {discordRole.Name}.");
                        }
                        success++;
                    }
                    catch (Exception ex)
                    {
                        errors++;
                        failed.Add(member.Username);
                        _logger.Error(ex);
                    }
                }

                _logger.Info($"Finished assigning {string.Join(",", roles)} roles.");

                await message.RespondAsync
                (
                    $"{success}/{guild.MemberCount} members were assigned the " + (defaultCityFeed ? "default city feed" : string.Join(",", roles)) + $" roles and {errors} member's roles were not set." +
                    (failed.Count == 0 ? "" : "\r\nList of users role assignment failed:\r\n" + string.Join(Environment.NewLine, failed))
                );
            })
            {
                IsBackground = true
            }.Start();
        }
Example #5
0
        private AlarmList LoadAlarms(string alarmsFilePath)
        {
            _logger.Trace($"WebhookManager::LoadAlarms [AlarmsFilePath={alarmsFilePath}]");

            if (!File.Exists(alarmsFilePath))
            {
                _logger.Error($"Failed to load file alarms file '{alarmsFilePath}'...");
                return(null);
            }

            var alarmData = File.ReadAllText(alarmsFilePath);

            if (string.IsNullOrEmpty(alarmData))
            {
                _logger.Error($"Failed to load '{alarmsFilePath}', file is empty...");
                return(null);
            }

            var alarms = JsonConvert.DeserializeObject <AlarmList>(alarmData);

            if (alarms == null)
            {
                _logger.Error($"Failed to deserialize the alarms file '{alarmsFilePath}', make sure you don't have any json syntax errors.");
                return(null);
            }

            _logger.Info($"Alarms file {alarmsFilePath} was loaded successfully.");

            alarms.Alarms.ForEach(x =>
            {
                if (x.Geofences != null)
                {
                    foreach (var geofenceName in x.Geofences)
                    {
                        var geofences = Geofences.Where(g => g.Name.Equals(geofenceName, StringComparison.OrdinalIgnoreCase) ||
                                                        g.Filename.Equals(geofenceName, StringComparison.OrdinalIgnoreCase)).ToList();

                        if (geofences.Any())
                        {
                            x.GeofenceItems.AddRange(geofences);
                        }
                        else
                        {
                            _logger.Warn($"No geofences were found matching the name or filename \"{geofenceName}\" (for alarm \"{x.Name}\")");
                        }
                    }
                }

                x.LoadAlerts();

                x.LoadFilters();
            });

            return(alarms);
        }
Example #6
0
        public void ParseData(string data)
        {
            try
            {
                if (string.IsNullOrEmpty(data))
                {
                    return;
                }

                //File.AppendAllText("debug.txt", data + "\r\n");

                var obj = JsonConvert.DeserializeObject <dynamic>(data);
                if (obj == null)
                {
                    return;
                }

                foreach (dynamic part in obj)
                {
                    string  type    = Convert.ToString(part["type"]);
                    dynamic message = part["message"];

                    switch (type)
                    {
                    case "pokemon":
                        ParsePokemon(message);
                        break;

                    //case "gym":
                    //    ParseGym(message);
                    //    break;
                    //case "gym-info":
                    //case "gym_details":
                    //    ParseGymInfo(message);
                    //    break;
                    //case "egg":
                    case "raid":
                        ParseRaid(message);
                        break;
                        //case "tth":
                        //case "scheduler":
                        //    ParseTth(message);
                        //    break;
                    }
                }
            }
            catch (Exception ex)
            {
                Utils.LogError(ex);

                _logger.Error(ex);
                _logger.Info("{0}", Convert.ToString(data));
            }
        }
Example #7
0
        private AlarmList LoadAlarms(string alarmsFilePath)
        {
            _logger.Trace($"WebhookManager::LoadAlarms [AlarmsFilePath={alarmsFilePath}]");

            if (!File.Exists(alarmsFilePath))
            {
                _logger.Error($"Failed to load file alarms file '{alarmsFilePath}'...");
                return(null);
            }

            var alarmData = File.ReadAllText(alarmsFilePath);

            if (string.IsNullOrEmpty(alarmData))
            {
                _logger.Error($"Failed to load '{alarmsFilePath}', file is empty...");
                return(null);
            }

            var alarms = JsonConvert.DeserializeObject <AlarmList>(alarmData);

            if (alarms == null)
            {
                _logger.Error($"Failed to deserialize the alarms file '{alarmsFilePath}', make sure you don't have any json syntax errors.");
                return(null);
            }

            _logger.Info($"Alarms file {alarmsFilePath} was loaded successfully.");

            alarms.Alarms.ForEach(x =>
            {
                var geofences = x.LoadGeofence();
                for (var i = 0; i < geofences.Count; i++)
                {
                    var geofence = geofences[i];
                    if (!Geofences.ContainsKey(geofence.Name))
                    {
                        Geofences.Add(geofence.Name, geofence);
                        _logger.Debug($"Geofence file loaded for {x.Name}...");
                    }
                }

                x.LoadAlerts();

                x.LoadFilters();
            });

            return(alarms);
        }
Example #8
0
        /// <summary>
        /// Instantiates a new <see cref="DatabaseMigrator"/> class
        /// </summary>
        public DatabaseMigrator()
        {
            // Create the metadata table
            Execute(Strings.SQL_CREATE_TABLE_METADATA).GetAwaiter().GetResult();

            // Get current version from metadata table
            var currentVersion = int.Parse(GetMetadata("DB_VERSION")?.Value ?? "0");

            // Get newest version from migration files
            var newestVersion = GetNewestDbVersion();

            _logger.Info($"Current: {currentVersion}, Latest: {newestVersion}");

            // Attempt to migrate the database
            Migrate(currentVersion, newestVersion).GetAwaiter().GetResult();
        }
Example #9
0
        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.");
        }
Example #10
0
        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")));
        }
Example #11
0
        public bool RemoveAllQuests(ulong userId)
        {
            _logger.Info($"SubscriptionManager::RemoveAllQuests [UserId={userId}]");

            using (var conn = DataAccessLayer.CreateFactory().Open())
            {
                var subscription = conn.LoadSingleById <SubscriptionObject>(userId);
                if (subscription == null)
                {
                    //Not subscribed.
                    return(true);
                }

                var result = conn.DeleteAll(subscription.Quests);
                return(result > 0);
            }
        }
Example #12
0
        private bool CreateDefaultTables()
        {
            _logger.Trace($"SubscriptionManager::CreateDefaultTables");

            if (!IsDbConnectionOpen())
            {
                throw new Exception("Not connected to database.");
            }

            try
            {
                /*
                 * var conn = GetConnection();
                 * if (!conn.CreateTableIfNotExists<Metadata>())
                 * {
                 *  _logger.Debug($"Table Metadata already exists.");
                 * }
                 * if (!conn.CreateTableIfNotExists<SubscriptionObject>())
                 * {
                 *  _logger.Debug($"Table SubscriptionObject already exists.");
                 * }
                 * if (!conn.CreateTableIfNotExists<PokemonSubscription>())
                 * {
                 *  _logger.Debug($"Table PokemonSubscription already exists.");
                 * }
                 * if (!conn.CreateTableIfNotExists<PvPSubscription>())
                 * {
                 *  _logger.Debug($"Table PvPSubscription already exists.");
                 * }
                 * if (!conn.CreateTableIfNotExists<RaidSubscription>())
                 * {
                 *  _logger.Debug($"Table RaidSubscription already exists.");
                 * }
                 * if (!conn.CreateTableIfNotExists<GymSubscription>())
                 * {
                 *  _logger.Debug($"Table GymSubscription already exists.");
                 * }
                 * if (!conn.CreateTableIfNotExists<QuestSubscription>())
                 * {
                 *  _logger.Debug($"Table QuestSubscription already exists.");
                 * }
                 * if (!conn.CreateTableIfNotExists<InvasionSubscription>())
                 * {
                 *  _logger.Debug($"Table InvasionSubscription already exists.");
                 * }
                 */

                _logger.Info($"Database tables created.");
                return(true);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
            }
            return(false);
        }
Example #13
0
        private async Task Client_Ready(ReadyEventArgs e)
        {
            _logger.Trace($"Bot::Client_Ready [{e.Client.CurrentUser.Username}]");

            //var version = AssemblyUtils.AssemblyVersion;
            //var cleanedVersion = version.Substring(0, version.LastIndexOf('.'));
            await _client.UpdateStatusAsync(new DiscordGame($"Reporting raids..."));

            foreach (var user in _client.Presences)
            {
                _logger.Info($"User: {user.Key}: {user.Value.User.Username}");
            }
        }
Example #14
0
        /// <summary>
        /// Instantiates a new <see cref="DatabaseMigrator"/> class
        /// </summary>
        public DatabaseMigrator()
        {
            // Create directory if not exists
            var dir = Path.GetDirectoryName(CurrentDatabaseVersionPath);

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            // Get current version from metadata table
            var currentVersion = GetCurrentVersion();

            if (currentVersion == 0)
            {
                var result = SetCurrentVersion(currentVersion);
                if (!result)
                {
                    _logger.Error($"Failed to set current database version: {currentVersion}");
                    Environment.Exit(-1);
                }
            }

            // Get newest version from migration files
            var newestVersion = GetNewestDbVersion();

            _logger.Info($"Current: {currentVersion}, Latest: {newestVersion}");

            // Attempt to migrate the database
            if (currentVersion < newestVersion)
            {
                // 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);
            }
            Migrate(currentVersion, newestVersion).GetAwaiter().GetResult();
        }
Example #15
0
        /// <summary>
        /// Instantiates a new <see cref="DatabaseMigrator"/> class
        /// </summary>
        public DatabaseMigrator()
        {
            // Create the metadata table
            Execute(Strings.SQL_CREATE_TABLE_METADATA).GetAwaiter().GetResult();

            // Get current version from metadata table
            var currentVersion = int.Parse(GetMetadata("DB_VERSION")?.Value ?? "0");

            // Get newest version from migration files
            var newestVersion = GetNewestDbVersion();

            _logger.Info($"Current: {currentVersion}, Latest: {newestVersion}");

            // Attempt to migrate the database
            if (currentVersion < newestVersion)
            {
                // 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);
            }
            Migrate(currentVersion, newestVersion).GetAwaiter().GetResult();
        }
Example #16
0
        public bool Resign(string megaLink, string version)
        {
            var fileName          = $"J{version}.ipa";
            var releaseName       = Path.Combine(ReleasesFolder, fileName);
            var releaseNameSigned = Path.Combine(
                ReleasesFolder,
                Path.GetFileNameWithoutExtension(fileName) + "Signed.ipa"
                );

            SignedReleaseFileName = releaseNameSigned;
            if (File.Exists(releaseName))
            {
                // Already exists
                _logger.Info($"Latest ipa already downloaded, skipping...");
            }
            else
            {
                // Download new version
                _logger.Info($"Downloading IPA from {megaLink} to {releaseName}");
                if (!DownloadFile(megaLink, releaseName))
                {
                    _logger.Warn($"Failed to download IPA from {megaLink}, is megatools installed?");
                    return(false);
                }
            }
            if (File.Exists(releaseNameSigned))
            {
                _logger.Info($"Signed IPA of latest already exists!");
                // Already exists
                return(true);
            }

            var result = InternalResignApp(releaseName, releaseNameSigned);

            if (!result)
            {
                _logger.Error($"Unknown error occurred while resigning ipa file {releaseName}");
            }
            //Deploy(releaseNameSigned, Strings.All);
            return(result);
        }
Example #17
0
        public void Start()
        {
            _logger.Trace("Start");
            _logger.Info("Connecting to Discord...");

            // TODO: Fails on M1 while debugging
            _client.ConnectAsync();
            _server.Start();
        }
Example #18
0
        /// <summary>
        /// Discord bot class
        /// </summary>
        /// <param name="config">Configuration settings</param>
        public Bot(Config whConfig)
        {
            _logger.Trace($"WhConfig [Servers={whConfig.Servers.Count}]");
            _servers  = new Dictionary <ulong, DiscordClient>();
            _whConfig = whConfig;

            // Set unhandled exception event handler
            AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;

            // Create a DiscordClient object per Discord server in config
            var keys = _whConfig.Servers.Keys.ToList();

            for (var i = 0; i < keys.Count; i++)
            {
                var guildId = keys[i];
                var server  = _whConfig.Servers[guildId];
                var client  = new DiscordClient(new DiscordConfiguration
                {
                    AutomaticGuildSync = true,
                    AutoReconnect      = true,
                    EnableCompression  = true,
                    Token                 = server.Token,
                    TokenType             = TokenType.Bot,
                    UseInternalLogHandler = true
                });

                // If you are on Windows 7 and using .NETFX, install
                // DSharpPlus.WebSocket.WebSocket4Net from NuGet,
                // add appropriate usings, and uncomment the following
                // line
                //client.SetWebSocketClient<WebSocket4NetClient>();

                // If you are on Windows 7 and using .NET Core, install
                // DSharpPlus.WebSocket.WebSocket4NetCore from NuGet,
                // add appropriate usings, and uncomment the following
                // line
                //client.SetWebSocketClient<WebSocket4NetCoreClient>();

                // If you are using Mono, install
                // DSharpPlus.WebSocket.WebSocketSharp from NuGet,
                // add appropriate usings, and uncomment the following
                // line
                //client.SetWebSocketClient<WebSocketSharpClient>();

                client.Ready          += Client_Ready;
                client.GuildAvailable += Client_GuildAvailable;
                //_client.MessageCreated += Client_MessageCreated;
                client.ClientErrored += Client_ClientErrored;
                client.DebugLogger.LogMessageReceived += DebugLogger_LogMessageReceived;

                _logger.Info($"Configured Discord server {guildId}");
                if (!_servers.ContainsKey(guildId))
                {
                    _servers.Add(guildId, client);
                }

                // Wait 3 seconds between initializing Discord clients
                Task.Delay(3000).GetAwaiter().GetResult();
            }
        }
Example #19
0
        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>();
            }
        }
Example #20
0
        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].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 || loc == null)
                    {
                        continue;
                    }

                    if (!member.HasSupporterRole(_whConfig.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.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 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(loc.Name.ToLower());

                    // If set distance does not match and no geofences match, then skip Pokemon...
                    if (!distanceMatches && !geofenceMatches)
                    {
                        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;
        }
Example #21
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;
        }
Example #22
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;
        }
Example #23
0
        private async Task Client_Ready(ReadyEventArgs e)
        {
            _logger.Info($"Connected.");

            await _client.UpdateStatusAsync(new DiscordGame("Your lobby is waiting..."));
        }
        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}");
                    }
                }
            });
        }
Example #25
0
        public async Task ProcessAlarms(PokemonData pkmn, Dictionary <string, List <AlarmObject> > alarms)
        {
            if (pkmn == null)
            {
                return;
            }
            if (alarms == null || alarms.Count == 0)
            {
                return;
            }

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

            if (!_db.Pokemon.ContainsKey(pkmn.Id.ToString()))
            {
                return;
            }
            var pokemon = _db.Pokemon[pkmn.Id.ToString()];

            if (pokemon == null)
            {
                return;
            }

            if (_client == null)
            {
                return;
            }

            foreach (var item in alarms)
            {
                foreach (var alarm in item.Value)
                {
                    //if (string.Compare(alarm.Geofence.Name, item.Key, true) != 0)
                    //    continue;

                    if (!MatchesGeofenceFilter(alarm.Geofence, new Location(pkmn.Latitude, pkmn.Longitude)))
                    {
                        continue;
                    }

                    if (!_filters.AlarmMatchesIV(pkmn.IV, alarm.Filters))
                    {
                        continue;
                    }

                    var embed = BuildEmbedPokemonFromAlarm(pkmn, alarm);
                    if (embed == null)
                    {
                        continue;
                    }

                    _logger.Info($"Notifying alarm {alarm.Name} that a {pokemon.Name} {pkmn.CP}CP {pkmn.IV} IV L{pkmn.Level} has spawned...");
                    Notify(pokemon.Name, embed);

                    await _client.SendMessage(alarm.Webhook, null, embed);
                }
            }
        }
Example #26
0
        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:N0}' meters at '{distance:N0}' meters away.");
                            continue;
                        }
                        _logger.Debug($"Distance matches for user {member.DisplayName} ({member.Id}) for Pokemon {pokemon.Name}: {distance}/{user.DistanceM}");
                    }

                    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)) &&
                                                                    (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;
        }
Example #27
0
        /// <summary>
        /// Discord bot class
        /// </summary>
        /// <param name="whConfig">Configuration settings</param>
        public Bot(WhConfigHolder whConfig)
        {
            _logger.Trace($"WhConfig [Servers={whConfig.Instance.Servers.Count}, Port={whConfig.Instance.WebhookPort}]");
            _servers  = new Dictionary <ulong, DiscordClient>();
            _whConfig = whConfig;
            _whm      = new WebhookController(_whConfig);

            // Build form lists for icons
            IconFetcher.Instance.SetIconStyles(_whConfig.Instance.IconStyles);

            // Set translation language
            Translator.Instance.SetLocale(_whConfig.Instance.Locale);

            // Set database connection strings to static properties so we can access within our extension classes
            DataAccessLayer.ConnectionString        = _whConfig.Instance.Database.Main.ToString();
            DataAccessLayer.ScannerConnectionString = _whConfig.Instance.Database.Scanner.ToString();

            // Set unhandled exception event handler
            AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;

            // Initialize and start midnight reset timer
            var midnight = new DandTSoftware.Timers.MidnightTimer();

            midnight.TimeReached += async(e) => await OnMidnightTimer();

            midnight.Start();

            // Initialize the subscription processor if at least one Discord server wants custom notifications
            // and start database migrator
            if (_whConfig.Instance.Servers.Values.ToList().Exists(x => x.Subscriptions.Enabled))
            {
                // Start database migrator
                var migrator = new DatabaseMigrator();
                while (!migrator.Finished)
                {
                    Thread.Sleep(50);
                }

                _subProcessor = new SubscriptionProcessor(_servers, _whConfig, _whm);
            }

            // Create a DiscordClient object per Discord server in config
            foreach (var(guildId, serverConfig) in _whConfig.Instance.Servers)
            {
                serverConfig.LoadDmAlerts();
                var client = new DiscordClient(new DiscordConfiguration
                {
                    AutomaticGuildSync = true,
                    AutoReconnect      = true,
                    EnableCompression  = true,
                    Token                 = serverConfig.Token,
                    TokenType             = TokenType.Bot,
                    UseInternalLogHandler = true
                });

                // If you are on Windows 7 and using .NETFX, install
                // DSharpPlus.WebSocket.WebSocket4Net from NuGet,
                // add appropriate usings, and uncomment the following
                // line
                //client.SetWebSocketClient<WebSocket4NetClient>();

                // If you are on Windows 7 and using .NET Core, install
                // DSharpPlus.WebSocket.WebSocket4NetCore from NuGet,
                // add appropriate usings, and uncomment the following
                // line
                //client.SetWebSocketClient<WebSocket4NetCoreClient>();

                // If you are using Mono, install
                // DSharpPlus.WebSocket.WebSocketSharp from NuGet,
                // add appropriate usings, and uncomment the following
                // line
                //client.SetWebSocketClient<WebSocketSharpClient>();

                client.Ready              += Client_Ready;
                client.GuildAvailable     += Client_GuildAvailable;
                client.GuildMemberUpdated += Client_GuildMemberUpdated;
                //_client.MessageCreated += Client_MessageCreated;
                client.ClientErrored += Client_ClientErrored;
                client.DebugLogger.LogMessageReceived += DebugLogger_LogMessageReceived;

                // Configure Discord interactivity module
                var interactivity = client.UseInteractivity
                                    (
                    new InteractivityConfiguration
                {
                    // default pagination behaviour to just ignore the reactions
                    PaginationBehaviour = TimeoutBehaviour.Ignore,

                    // default pagination timeout to 5 minutes
                    PaginationTimeout = TimeSpan.FromMinutes(5),

                    // default timeout for other actions to 2 minutes
                    Timeout = TimeSpan.FromMinutes(2)
                }
                                    );

                // Build the dependency collection which will contain our objects that can be globally used within each command module
                DependencyCollection dep;
                using (var d = new DependencyCollectionBuilder())
                {
                    d.AddInstance(new Dependencies(interactivity, _whm, _subProcessor, _whConfig, new StripeService(_whConfig.Instance.StripeApiKey)));
                    dep = d.Build();
                }

                // Discord commands configuration
                var commands = client.UseCommandsNext
                               (
                    new CommandsNextConfiguration
                {
                    StringPrefix = serverConfig.CommandPrefix?.ToString(),
                    EnableDms    = true,
                    // If command prefix is null, allow for mention prefix
                    EnableMentionPrefix = string.IsNullOrEmpty(serverConfig.CommandPrefix),
                    // Use DSharpPlus's built-in help formatter
                    EnableDefaultHelp    = true,
                    CaseSensitive        = false,
                    IgnoreExtraArguments = true,
                    Dependencies         = dep
                }
                               );
                commands.CommandExecuted += Commands_CommandExecuted;
                commands.CommandErrored  += Commands_CommandErrored;
                // Register Discord command handler classes
                commands.RegisterCommands <Owner>();
                commands.RegisterCommands <Event>();
                commands.RegisterCommands <Nests>();
                commands.RegisterCommands <ShinyStats>();
                commands.RegisterCommands <Gyms>();
                commands.RegisterCommands <Quests>();
                commands.RegisterCommands <Settings>();
                if (serverConfig.Subscriptions.Enabled)
                {
                    commands.RegisterCommands <Notifications>();
                }
                if (serverConfig.EnableCities)
                {
                    commands.RegisterCommands <Feeds>();
                }

                _logger.Info($"Configured Discord server {guildId}");
                if (!_servers.ContainsKey(guildId))
                {
                    _servers.Add(guildId, client);
                }

                // Wait 3 seconds between initializing Discord clients
                Task.Delay(3000).GetAwaiter().GetResult();
            }

            RegisterConfigMonitor();
        }
Example #28
0
        private void InitializeTimer()
        {
            try
            {
#pragma warning disable RECS0165
                _timer = new Timer(async x =>
#pragma warning restore RECS0165
                {
                    foreach (var user in _db.Reminders)
                    {
                        var itemsToRemove = new List <Reminder>();
                        foreach (var reminder in user.Value)
                        {
                            _logger.Info($"Reminder for user {user.Key} {DateTime.UtcNow.Subtract(reminder.Time)} time left.");
                            if (reminder.Time.CompareTo(DateTime.UtcNow) <= 0)
                            {
                                var userToRemind = await _client.GetUser(user.Key);
                                if (userToRemind == null)
                                {
                                    _logger.Error($"Failed to find discord user with id '{user.Key}'.");
                                    continue;
                                }

                                _logger.Info($"NOTIFYING USER OF REMINDER: {reminder.Message}");
                                if (reminder.Where == 0)
                                {
                                    await _client.SendDirectMessage(userToRemind, $":alarm_clock: **Reminder:** {reminder.Message}", null);
                                }
                                else
                                {
                                    var channel = await _client.GetChannel(reminder.Where);
                                    if (channel == null)
                                    {
                                        _logger.Error($"Failed to find channel {reminder.Where} that reminder should be sent to, sending via DM instead...");
                                        await _client.SendDirectMessage(userToRemind, $":alarm_clock: **Reminder:** {reminder.Message}", null);
                                    }
                                    else
                                    {
                                        await channel.SendMessageAsync($":alarm_clock: {userToRemind.Mention} **Reminder:** {reminder.Message}");
                                    }
                                }
                                itemsToRemove.Add(reminder);
                            }
                        }

                        foreach (var remove in itemsToRemove)
                        {
                            user.Value.Remove(remove);
                        }
                        _db.Reminders.TryUpdate(user.Key, user.Value, user.Value);
                    }

                    ChangeToClosestInterval();
                    _db.Save();
                },
                                   null,
                                   TimeSpan.FromSeconds(INITIAL_DELAY),  // Time that message should fire after bot has started
                                   TimeSpan.FromSeconds(INITIAL_DELAY)); //time after which message should repeat (timout.infinite for no repeat)
            }
            catch (Exception ex)
            {
                Utils.LogError(ex);
            }
        }
Example #29
0
        public async Task ProcessPokemonSubscription(PokemonData pkmn)
        {
            if (!_whConfig.Discord.EnableSubscriptions)
            {
                return;
            }

            var db = Database.Instance;

            if (!db.Pokemon.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        = db.Pokemon[pkmn.Id];
            var matchesIV      = false;
            var matchesLvl     = false;
            var matchesGender  = false;
            var matchesAttack  = false;
            var matchesDefense = false;
            var matchesStamina = false;

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

                    if (!user.Enabled)
                    {
                        continue;
                    }

                    try
                    {
                        member = await _client.GetMemberById(_whConfig.Discord.GuildId, user.UserId);
                    }
                    catch (Exception ex)
                    {
                        _logger.Debug($"FAILED TO GET MEMBER BY ID {user.UserId}");
                        _logger.Error(ex);
                        continue;
                    }

                    if (!member.HasSupporterRole(_whConfig.Discord.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;
                    }

                    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 = pkmn.Id.GetPokemonForm(pkmn.FormId.ToString());
                    subscribedPokemon = user.Pokemon.FirstOrDefault(x => x.PokemonId == pkmn.Id && ((x.Form == null || x.Form == string.Empty) || string.Compare(x.Form, form, true) == 0));
                    if (subscribedPokemon == null)
                    {
                        _logger.Info($"User {member.Username} not subscribed to Pokemon {pokemon.Name} (Form: {form}).");
                        continue;
                    }

                    matchesIV = _whm.Filters.MatchesIV(pkmn.IV, subscribedPokemon.MinimumIV);
                    //var matchesCP = _whm.Filters.MatchesCpFilter(pkmn.CP, subscribedPokemon.MinimumCP);
                    matchesLvl     = _whm.Filters.MatchesLvl(pkmn.Level, subscribedPokemon.MinimumLevel);
                    matchesGender  = _whm.Filters.MatchesGender(pkmn.Gender, subscribedPokemon.Gender);
                    matchesAttack  = _whm.Filters.MatchesAttack(pkmn.Attack, subscribedPokemon.Attack);
                    matchesDefense = _whm.Filters.MatchesDefense(pkmn.Defense, subscribedPokemon.Defense);
                    matchesStamina = _whm.Filters.MatchesStamina(pkmn.Stamina, subscribedPokemon.Stamina);

                    if (!(
                            (!subscribedPokemon.HasStats && matchesIV && matchesLvl && matchesGender) ||
                            (subscribedPokemon.HasStats && matchesAttack && matchesDefense && matchesStamina)
                            ))
                    {
                        continue;
                    }

                    //_logger.Debug($"Notifying user {member.Username} that a {pokemon.Name} {pkmn.CP}CP {pkmn.IV} IV L{pkmn.Level} has spawned...");

                    var iconStyle = Manager.GetUserIconStyle(user);
                    var embed     = await pkmn.GeneratePokemonMessage(_client, _whConfig, pkmn, null, loc.Name, string.Format(_whConfig.IconStyles[iconStyle], pkmn.Id, pkmn.FormId));

                    _queue.Enqueue(new Tuple <DiscordUser, string, DiscordEmbed>(member, pokemon.Name, embed));

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

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

            await Task.CompletedTask;
        }