예제 #1
0
            public async Task Content(CommandContext ctx, [RemainingText, Description("Content IDs to scrape, such as `UP0006-NPUB30592_00-MONOPOLYPSNNA000`")] string contentIds)
            {
                if (string.IsNullOrEmpty(contentIds))
                {
                    await ctx.ReactWithAsync(Config.Reactions.Failure, "No IDs were specified").ConfigureAwait(false);

                    return;
                }

                var matches      = PsnScraper.ContentIdMatcher.Matches(contentIds.ToUpperInvariant());
                var itemsToCheck = matches.Select(m => m.Groups["content_id"].Value).ToList();

                if (itemsToCheck.Count == 0)
                {
                    await ctx.ReactWithAsync(Config.Reactions.Failure, "No IDs were specified").ConfigureAwait(false);

                    return;
                }

                foreach (var id in itemsToCheck)
                {
                    PsnScraper.CheckContentIdAsync(ctx, id, Config.Cts.Token);
                }

                await ctx.ReactWithAsync(Config.Reactions.Success, $"Added {itemsToCheck.Count} ID{StringUtils.GetSuffix(itemsToCheck.Count)} to the scraping queue").ConfigureAwait(false);
            }
예제 #2
0
        internal static async Task Main(string[] args)
        {
            var singleInstanceCheckThread = new Thread(() =>
            {
                using (var instanceLock = new Mutex(false, @"Global\RPCS3 Compatibility Bot"))
                {
                    if (instanceLock.WaitOne(1000))
                    {
                        try
                        {
                            InstanceCheck.Release();
                            ShutdownCheck.Wait();
                        }
                        finally
                        {
                            instanceLock.ReleaseMutex();
                        }
                    }
                }
            });
            var rpcs3UpdateCheckThread = new Thread(client =>
            {
                try
                {
                    while (!Config.Cts.IsCancellationRequested)
                    {
                        try
                        {
                            CompatList.UpdatesCheck.CheckForRpcs3Updates((DiscordClient)client, null).ConfigureAwait(false).GetAwaiter().GetResult();
                        }
                        catch { }
                        Task.Delay(TimeSpan.FromHours(1), Config.Cts.Token).ConfigureAwait(false).GetAwaiter().GetResult();
                    }
                }
                catch (TaskCanceledException) { }
            })
            {
                IsBackground = true
            };

            try
            {
                singleInstanceCheckThread.Start();
                if (!InstanceCheck.Wait(1000))
                {
                    Config.Log.Fatal("Another instance is already running.");
                    return;
                }

                if (string.IsNullOrEmpty(Config.Token))
                {
                    Config.Log.Fatal("No token was specified.");
                    return;
                }
                var amdDriverRefreshTask = AmdDriverVersionProvider.RefreshAsync();

                using (var db = new BotDb())
                    if (!await DbImporter.UpgradeAsync(db, Config.Cts.Token))
                    {
                        return;
                    }

                using (var db = new ThumbnailDb())
                    if (!await DbImporter.UpgradeAsync(db, Config.Cts.Token))
                    {
                        return;
                    }

                var psnScrappingTask    = new PsnScraper().RunAsync(Config.Cts.Token);
                var gameTdbScrapingTask = GameTdbScraper.RunAsync(Config.Cts.Token);
                await amdDriverRefreshTask.ConfigureAwait(false);

                try
                {
                    if (!Directory.Exists(Config.IrdCachePath))
                    {
                        Directory.CreateDirectory(Config.IrdCachePath);
                    }
                }
                catch (Exception e)
                {
                    Config.Log.Warn(e, $"Failed to create new folder {Config.IrdCachePath}: {e.Message}");
                }

                var config = new DiscordConfiguration
                {
                    Token     = Config.Token,
                    TokenType = TokenType.Bot,
                    //UseInternalLogHandler = true,
                    //LogLevel = LogLevel.Debug,
                };
                using (var client = new DiscordClient(config))
                {
                    var commands = client.UseCommandsNext(new CommandsNextConfiguration
                    {
                        StringPrefixes = new[] { Config.CommandPrefix },
                        Services       = new ServiceCollection().BuildServiceProvider(),
                    });
                    commands.RegisterConverter(new CustomDiscordChannelConverter());
                    commands.RegisterCommands <Misc>();
                    commands.RegisterCommands <CompatList>();
                    commands.RegisterCommands <Sudo>();
                    commands.RegisterCommands <Antipiracy>();
                    commands.RegisterCommands <Warnings>();
                    commands.RegisterCommands <Explain>();
                    commands.RegisterCommands <Psn>();
                    commands.RegisterCommands <Invites>();
                    commands.RegisterCommands <Moderation>();
                    commands.RegisterCommands <Ird>();

                    client.Ready += async r =>
                    {
                        Config.Log.Info("Bot is ready to serve!");
                        Config.Log.Info("");
                        Config.Log.Info($"Bot user id : {r.Client.CurrentUser.Id} ({r.Client.CurrentUser.Username})");
                        Config.Log.Info($"Bot admin id : {Config.BotAdminId} ({(await r.Client.GetUserAsync(Config.BotAdminId)).Username})");
                        Config.Log.Info("");
                    };
                    client.GuildAvailable += async gaArgs =>
                    {
                        if (gaArgs.Guild.Id != Config.BotGuildId)
                        {
#if DEBUG
                            Config.Log.Warn($"Unknown discord server {gaArgs.Guild.Id} ({gaArgs.Guild.Name})");
#else
                            Config.Log.Warn($"Unknown discord server {gaArgs.Guild.Id} ({gaArgs.Guild.Name}), leaving...");
                            await gaArgs.Guild.LeaveAsync().ConfigureAwait(false);
#endif
                            return;
                        }

                        Config.Log.Info($"Server {gaArgs.Guild.Name} is available now");
                        Config.Log.Info($"Checking moderation backlogs in {gaArgs.Guild.Name}...");
                        try
                        {
                            await Task.WhenAll(
                                Starbucks.CheckBacklogAsync(gaArgs.Client, gaArgs.Guild).ContinueWith(_ => Config.Log.Info($"Starbucks backlog checked in {gaArgs.Guild.Name}.")),
                                DiscordInviteFilter.CheckBacklogAsync(gaArgs.Client, gaArgs.Guild).ContinueWith(_ => Config.Log.Info($"Discord invites backlog checked in {gaArgs.Guild.Name}."))
                                ).ConfigureAwait(false);
                        }
                        catch (Exception e)
                        {
                            Config.Log.Warn(e, "Error running backlog tasks");
                        }
                        Config.Log.Info($"All moderation backlogs checked in {gaArgs.Guild.Name}.");
                    };
                    client.GuildUnavailable += guArgs =>
                    {
                        Config.Log.Warn($"{guArgs.Guild.Name} is unavailable");
                        return(Task.CompletedTask);
                    };

                    client.MessageReactionAdded += Starbucks.Handler;

                    client.MessageCreated += AntipiracyMonitor.OnMessageCreated; // should be first
                    client.MessageCreated += ProductCodeLookup.OnMessageCreated;
                    client.MessageCreated += LogParsingHandler.OnMessageCreated;
                    client.MessageCreated += LogAsTextMonitor.OnMessageCreated;
                    client.MessageCreated += DiscordInviteFilter.OnMessageCreated;
                    client.MessageCreated += BotShutupHandler.OnMessageCreated;
                    client.MessageCreated += NewBuildsMonitor.OnMessageCreated;
                    client.MessageCreated += TableFlipMonitor.OnMessageCreated;

                    client.MessageUpdated += AntipiracyMonitor.OnMessageUpdated;
                    client.MessageUpdated += DiscordInviteFilter.OnMessageUpdated;

                    client.MessageDeleted += ThumbnailCacheMonitor.OnMessageDeleted;

                    client.UserUpdated        += UsernameSpoofMonitor.OnUserUpdated;
                    client.GuildMemberAdded   += UsernameSpoofMonitor.OnMemberAdded;
                    client.GuildMemberUpdated += UsernameSpoofMonitor.OnMemberUpdated;

                    client.DebugLogger.LogMessageReceived += (sender, eventArgs) =>
                    {
                        Action <string> logLevel = Config.Log.Info;
                        if (eventArgs.Level == LogLevel.Debug)
                        {
                            logLevel = Config.Log.Debug;
                        }
                        //else if (eventArgs.Level == LogLevel.Info)
                        //    logLevel = botLog.Info;
                        else if (eventArgs.Level == LogLevel.Warning)
                        {
                            logLevel = Config.Log.Warn;
                        }
                        else if (eventArgs.Level == LogLevel.Error)
                        {
                            logLevel = Config.Log.Error;
                        }
                        else if (eventArgs.Level == LogLevel.Critical)
                        {
                            logLevel = Config.Log.Fatal;
                        }
                        logLevel(eventArgs.Message);
                    };

                    try
                    {
                        await client.ConnectAsync();
                    }
                    catch (Exception e)
                    {
                        Config.Log.Fatal(e, "Terminating");
                        return;
                    }

                    if (args.Length > 1 && ulong.TryParse(args[1], out var channelId))
                    {
                        Config.Log.Info($"Found channelId: {args[1]}");
                        DiscordChannel channel;
                        if (channelId == InvalidChannelId)
                        {
                            channel = await client.GetChannelAsync(Config.ThumbnailSpamId).ConfigureAwait(false);

                            await channel.SendMessageAsync("Bot has suffered some catastrophic failure and was restarted").ConfigureAwait(false);
                        }
                        else
                        {
                            channel = await client.GetChannelAsync(channelId).ConfigureAwait(false);

                            await channel.SendMessageAsync("Bot is up and running").ConfigureAwait(false);
                        }
                    }

                    Config.Log.Debug("Running RPC3 update check thread");
                    rpcs3UpdateCheckThread.Start(client);

                    while (!Config.Cts.IsCancellationRequested)
                    {
                        if (client.Ping > 1000)
                        {
                            await client.ReconnectAsync();
                        }
                        await Task.Delay(TimeSpan.FromMinutes(1), Config.Cts.Token).ContinueWith(dt => { /* in case it was cancelled */ }).ConfigureAwait(false);
                    }
                }
                await Task.WhenAll(
                    psnScrappingTask,
                    gameTdbScrapingTask
                    ).ConfigureAwait(false);
            }
            catch (TaskCanceledException)
            {
            }
            catch (Exception e)
            {
                Config.Log.Fatal(e, $"Experienced catastrofic failure, attempting to restart...");
                Sudo.Bot.Restart(InvalidChannelId);
            }
            finally
            {
                ShutdownCheck.Release();
                if (singleInstanceCheckThread.IsAlive)
                {
                    singleInstanceCheckThread.Join(100);
                }
                if (rpcs3UpdateCheckThread.IsAlive)
                {
                    rpcs3UpdateCheckThread.Join(100);
                }
                Config.Log.Info("Exiting");
            }
        }