//public static void Main(string[] args) => new RiotApiClient().matchHistoryCheckLoop();

        // This method runs the core functionality of this component - checking match history and sending info over to the
        // Discord client whenever it detects a game loss.
        public async void checkMatchHistories(Object source, System.Timers.ElapsedEventArgs e)
        {
            Console.WriteLine("checking last match state for monitored summoners at {0}.", e.SignalTime);

            foreach (string summonerAcctId in StaticData.summonerToDiscordMappings.Keys)
            {
                try {
                    RelevantMatchInfo        lastMatchInfo            = null;
                    CancellationTokenSource  timeoutCancelTokenSource = new CancellationTokenSource();
                    Task <RelevantMatchInfo> retrieveTask             = this.retrieveLastMatchData(summonerAcctId);
                    var completedTask = await Task.WhenAny(retrieveTask, Task.Delay(10000, timeoutCancelTokenSource.Token));

                    if (completedTask == retrieveTask)
                    {
                        timeoutCancelTokenSource.Cancel();
                        lastMatchInfo = retrieveTask.Result;
                    }
                    else
                    {
                        Console.WriteLine("The operation has timed out.");
                        continue;
                    }

                    this.handleLastMatchEvent(lastMatchInfo);
                } catch (Exception ex) {
                    Console.WriteLine("The operation has failed: {0}. Skipping to next summoner...", ex.Message);
                    continue;
                }
            }
        }
        private int gameFinishedHandler(RelevantMatchInfo lastMatchInfo)
        {
            Console.WriteLine("A recently finished game was detected for {0}.", lastMatchInfo.summonerName);

            // If the last match has already been detected recently don't do anything
            if (lastMatchInfo.finishTime.Equals(this.lastMatchChecked.finishTime))
            {
                Console.WriteLine("The game was already checked.");
                return(1);
            }
            else if (!lastMatchInfo.winner)
            {
                Console.WriteLine("The game was lost!");
                // If game lost, announce the loss and assign the punishment role
                SocketTextChannel channel = this.discordSocketClient.GetChannel(StaticData.announcementChannelId) as SocketTextChannel;
                string            msg     = String.Format(this.lossAnnounceFmt, lastMatchInfo.summonerName, lastMatchInfo.championName, lastMatchInfo.kills, lastMatchInfo.deaths, lastMatchInfo.assists);
                // Special message for when the K/D ratio was particularly bad
                var    id        = StaticData.summonerToDiscordMappings[lastMatchInfo.accountId];
                string msgAppend = ((double)lastMatchInfo.kills / lastMatchInfo.deaths < 0.7) ? $"<@{id}> " + this.badLossMsg : this.standardLossMsg;
                channel.SendMessageAsync(msg + msgAppend, true);
                this.addOrRemoveRole(id, StaticData.punishmentRoleId, true);
            }
            else if (lastMatchInfo.winner)
            {
                Console.WriteLine("The game was won!");
                // If game won, remove the punishment role
                this.addOrRemoveRole(StaticData.summonerToDiscordMappings[lastMatchInfo.accountId], StaticData.punishmentRoleId, false);
            }

            this.lastMatchChecked = lastMatchInfo;
            return(0);
        }
 public DiscordApiClient(RiotApiClient riotApiClient)
 {
     this.discordSocketClient = new DiscordSocketClient();
     this.commandService      = new CommandService();
     this.riotApiClient       = riotApiClient;
     // Start with a blank last match checked
     this.lastMatchChecked = new RelevantMatchInfo();
 }
        private void handleLastMatchEvent(RelevantMatchInfo lastMatchInfo)
        {
            Console.WriteLine("Last game end time: {0} Current time: {1}", lastMatchInfo.finishTime, DateTime.Now);

            // Only fire off the gameFinished event for games that happened recently, and only if the discord client is ready to handle it
            if (lastMatchInfo == null)
            {
                Console.WriteLine("Could not retrieve info about last match for {0}.", lastMatchInfo.summonerName);
            }
            else if (DateTime.Now - lastMatchInfo.finishTime > TimeSpan.FromMinutes(20))
            {
                Console.WriteLine("Summoner {0} has not played a game recently enough to warrant a loss check.", lastMatchInfo.summonerName);
            }
            else
            {
                gameFinished(lastMatchInfo);
            }
        }