Esempio n. 1
0
 public Bet(LCSTeam winner, LCSTeam loser, decimal wager, ulong discordId)
 {
     Victor    = winner;
     Loser     = loser;
     Wager     = wager;
     DiscordID = discordId;
 }
Esempio n. 2
0
        public FutureMatch GetNextMatchForTeam(LCSTeam team)
        {
            var nextMatchesForTeam = this.Where(match => DateTime.Now < match.ScheduledTime + TimeSpan.FromMinutes(FUTURE_BUFFER_MINS) && (match.Team1.Equals(team) || match.Team2.Equals(team)));

            if (nextMatchesForTeam.Count() == 0)
            {
                return(null);
            }
            return(nextMatchesForTeam.First());
        }
Esempio n. 3
0
        /// <summary>
        /// Downloads the list of occurred LCS matches from lol.gamepedia.com
        /// </summary>
        /// <returns>A MatchRecord object containing the list of occurred LCS matches</returns>
        public static MatchRecord GetOnlineMatchRecord()
        {
            // Get HTML document
            string page_content;

            using (WebClient client = new WebClient())
            {
                page_content = client.DownloadString(URL_RECORD);
            }
            HtmlDocument html = new HtmlDocument();

            html.LoadHtml(page_content);
            HtmlNodeCollection raw_matches = html.DocumentNode.SelectNodes("//tr[contains(@class, 'mdv-allweeks mdv-week')]");

            // Get occurred mathes from HTML document
            MatchRecord record = new MatchRecord();

            foreach (HtmlNode node in raw_matches)
            {
                if (node.InnerLength > 1000) // Match has occurred
                {
                    HtmlNodeCollection teams = node.SelectNodes(".//span[@class='teamname']");
                    LCSTeam            team1 = LCSTeam.ParseTeam(teams[0].InnerText);
                    LCSTeam            team2 = LCSTeam.ParseTeam(teams[1].InnerText);

                    if (!string.IsNullOrEmpty(team1.Name) && !string.IsNullOrEmpty(team2.Name)) // Both teams in Match detected
                    {
                        HtmlNode win = node.SelectSingleNode(".//td[@class='md-winner']");
                        if (win != null) // Winner was found for this match
                        {
                            LCSTeam winner = LCSTeam.ParseTeam(win.InnerText);
                            if (winner.Equals(team1) || winner.Equals(team2)) // Make sure we detected the winning team correctly
                            {
                                LCSTeam other;
                                if (winner.Equals(team1))
                                {
                                    other = team2;
                                }
                                else
                                {
                                    other = team1;
                                }

                                record.Add(new MatchResult(winner, other));
                            }
                        }
                    }
                }
            }
            return(record);
        }
Esempio n. 4
0
        public static Schedule GetOnlineSchedule()
        {
            Schedule result = new Schedule();
            string   page_content;

            using (WebClient client = new WebClient())
            {
                page_content = client.DownloadString(URL_SCHEDULE);
            }
            HtmlDocument html = new HtmlDocument();

            html.LoadHtml(page_content);
            HtmlNode raw_schedule = html.DocumentNode.SelectSingleNode("//div[@class='mw-parser-output']/pre"); // Select schedule block

            foreach (string line in raw_schedule.InnerText.Split('\n'))
            {
                Match regex_schedule = REGEX_MATCHSCHEDULE.Match(line);
                if (regex_schedule.Success)
                {
                    string      t1              = regex_schedule.Groups[1].Value;
                    string      t2              = regex_schedule.Groups[2].Value;
                    string      year            = regex_schedule.Groups[3].Value;
                    string      month           = regex_schedule.Groups[4].Value;
                    string      day             = regex_schedule.Groups[5].Value;
                    string      hour            = regex_schedule.Groups[6].Value;
                    string      minute          = regex_schedule.Groups[7].Value;
                    DateTime    match_utctime   = DateTime.Parse($"{month}/{day}/{year} {hour}:{minute}:00", CultureInfo.InvariantCulture);
                    DateTime    match_time      = match_utctime + TimeZoneInfo.Local.GetUtcOffset(match_utctime + TimeZoneInfo.Local.BaseUtcOffset);
                    LCSTeam     team1           = LCSTeam.ParseTeam(t1);
                    LCSTeam     team2           = LCSTeam.ParseTeam(t2);
                    FutureMatch scheduled_match = new FutureMatch(team1, team2, match_time);
                    result.Add(scheduled_match);
                }
            }
            if (result.Count == 0)
            {
                Console.WriteLine("Failed to parse schedule.");
                return(null);
            }
            return(result);
        }
Esempio n. 5
0
 public MatchResult(LCSTeam winner, LCSTeam loser)
 {
     Victor = winner;
     Loser  = loser;
 }
Esempio n. 6
0
 public FutureMatch(LCSTeam t1, LCSTeam t2, DateTime time)
 {
     Team1         = t1;
     Team2         = t2;
     ScheduledTime = time;
 }
Esempio n. 7
0
 public Prediction(LCSTeam winner, LCSTeam loser, ulong discordId)
 {
     Victor    = winner;
     Loser     = loser;
     DiscordID = discordId;
 }
Esempio n. 8
0
        public async Task ProcessCommand(ulong discordId, SocketTextChannel replyChannel, string command, IList <string> args)
        {
            if (!Scoreboard.ContainsKey(discordId))
            {
                string name = ResolvePlayerName(discordId);
                Scoreboard[discordId] = new PlayerScore(discordId, name);
                Scoreboard.SaveToFile(SavePath);
                Console.WriteLine($"New player registered: {name} (DiscordID {discordId})");
            }

            command = command.ToLower().Trim();
            switch (command)
            {
            // Singlet commands
            case "score":
            case "money":
            case "myscore":
                if (Scoreboard.ContainsKey(discordId))
                {
                    var myScore = Scoreboard[discordId];
                    await SayInChannel(replyChannel, $"Score for {myScore.Name}:\n{myScore.Money:c} after {myScore.BetCount} bets ({myScore.MoneyFromBets:+$0.00;-$0.00;$0}). " +
                                       $"Prediction record: {myScore.PredictionsRight} - {myScore.PredictionsWrong} (+${myScore.MoneyFromPredictions})");
                }
                else
                {
                    await SayInChannel(replyChannel, $"You are not a registered player yet. Place a Bet or Prediction to start. " +
                                       $"You'll start with ${PlayerScore.STARTING_MONEY}.");
                }
                break;

            case "scores":
            case "allscores":
            case "scoreboard":
                if (Scoreboard.Count == 0)
                {
                    await SayInChannel(replyChannel, "The scoreboard is empty - there are no registered players yet.");
                }
                else
                {
                    string scoreMessage = "Scoreboard:\n";
                    var    sortedScores = Scoreboard.Values.ToList();
                    sortedScores.Sort((item1, item2) => item1.CompareTo(item2));
                    int place = 1;
                    foreach (var playerScore in sortedScores)
                    {
                        scoreMessage += $"{place++}. {playerScore.Name}: {playerScore.Money:c} ({playerScore.BetCount} bets, {playerScore.MoneyFromBets:+$0.00;-$0.00;$0}) " +
                                        $"Predictions: {playerScore.PredictionsRight} - {playerScore.PredictionsWrong} (+${playerScore.MoneyFromPredictions})\n";
                    }
                    await SayInChannel(replyChannel, scoreMessage);
                }
                break;

            case "games":
            case "upcoming":
            case "schedule":
                var futureGames = Schedule.Where(match => DateTime.Now < match.ScheduledTime + TimeSpan.FromMinutes(10));
                if (futureGames.Count() <= 0)
                {
                    await SayInChannel(replyChannel, "There are no games left in the season.");
                }
                else
                {
                    string scheduleMessage = "Upcoming LCS games:\n";
                    foreach (var futureGame in futureGames.Take(futureGames.Count() >= 5 ? 5 : futureGames.Count()))
                    {
                        scheduleMessage += futureGame.ToString() + "\n";
                    }
                    await SayInChannel(replyChannel, scheduleMessage);
                }
                break;

            case "mybets":
            case "bets":
                var myBets        = Bets.Where(bet => bet.DiscordID == discordId).ToList();
                var myPredictions = Predictions.Where(pred => pred.DiscordID == discordId).ToList();
                if (myBets.Count + myPredictions.Count == 0)
                {
                    await SayInChannel(replyChannel, "You do not have any active bets or predictions.");
                }
                else
                {
                    string betsString = "";
                    if (myBets.Count > 0)
                    {
                        betsString += "Your active bets:\n";
                        myBets.ForEach(bet => betsString += $"{bet.Wager:c} on {bet.Victor} beating {bet.Loser}\n");
                    }
                    if (myPredictions.Count > 0)
                    {
                        betsString += "Your predictions:\n";
                        myPredictions.ForEach(pred => betsString += $"{pred.Victor} will beat {pred.Loser}\n");
                    }
                    await SayInChannel(replyChannel, betsString);
                }
                break;

            case "allbets":
                if (Bets.Count + Predictions.Count == 0)
                {
                    await SayInChannel(replyChannel, "There are no active bets or predictions.");
                }
                else
                {
                    string betString = "";
                    if (Bets.Count > 0)
                    {
                        betString += "All active bets:\n";
                        Bets.ForEach(bet => betString += $"{ResolvePlayerName(bet.DiscordID)} bet {bet.Wager} on {bet.Victor} beating {bet.Loser}.\n");
                    }
                    if (Predictions.Count > 0)
                    {
                        betString += "Active predictions:\n";
                        Predictions.ForEach(pred => betString += $"{ResolvePlayerName(pred.DiscordID)} thinks {pred.Victor} will beat {pred.Loser}.\n");
                    }
                    await SayInChannel(replyChannel, betString);
                }
                break;

            // Parameterized commands
            case "nextgame":
            case "next":
                if (args.Count() == 0)
                {
                    await SayInChannel(replyChannel, "Enter a team to check the next game for (!next <Team>) or a pair of teams to find their next match (!next <Team1> <Team2>)");
                }
                else if (args.Count() > 2)
                {
                    await SayInChannel(replyChannel, "Usage: !next <Team> or !next <Team1> <Team2>");
                }
                else if (args.Count() == 1)
                {
                    LCSTeam team_check = LCSTeam.ParseTeam(args[0]);
                    if (team_check.ID == LCSTeam.TeamID.Unknown)
                    {
                        await SayInChannel(replyChannel, $"Unknown LCS team '{args[0]}'");
                    }
                    else
                    {
                        var nextMatchCheck = Schedule.GetNextMatchForTeam(team_check);
                        if (nextMatchCheck == null)
                        {
                            await SayInChannel(replyChannel, $"{team_check} has no matches left in the season.");
                        }
                        else
                        {
                            await SayInChannel(replyChannel, $"Next match for {team_check}: {nextMatchCheck}");
                        }
                    }
                }
                else     // Checking for match between two teams
                {
                    LCSTeam check1 = LCSTeam.ParseTeam(args[0]);
                    if (check1.ID == LCSTeam.TeamID.Unknown)
                    {
                        await SayInChannel(replyChannel, $"Unknown LCS team '{args[0]}'");

                        break;
                    }
                    LCSTeam check2 = LCSTeam.ParseTeam(args[1]);
                    if (check2.ID == LCSTeam.TeamID.Unknown)
                    {
                        await SayInChannel(replyChannel, $"Unknown LCS team '{args[1]}'");

                        break;
                    }
                    var nextMatchup = Schedule.GetNextMatchForMatchup(check1, check2);
                    if (nextMatchup == null)
                    {
                        await SayInChannel(replyChannel, $"{check1} and {check2} are not playing each other for the rest of the season.");
                    }
                    else
                    {
                        await SayInChannel(replyChannel, $"{check1} next plays {check2} at {nextMatchup.ScheduledTime:h:mm tt M/dd}");
                    }
                }
                break;

            case "predict":
                if (args.Count() == 0)
                {
                    await SayInChannel(replyChannel, "Enter a team to predict. (!predict <Team>)");
                }
                else if (args.Count() != 1)
                {
                    await SayInChannel(replyChannel, "Usage: !predict <Team>");
                }
                else
                {
                    LCSTeam team_pred = LCSTeam.ParseTeam(args[0]);
                    if (team_pred.ID == LCSTeam.TeamID.Unknown)
                    {
                        await SayInChannel(replyChannel, $"Unknown LCS team '{args[0]}'");
                    }
                    else
                    {
                        var nextScheduledMatch_pred = Schedule.GetNextMatchForTeam(team_pred);
                        if (nextScheduledMatch_pred == null)
                        {
                            await SayInChannel(replyChannel, $"Team {team_pred} has no games left in the season.");
                        }
                        else if (DateTime.Now > nextScheduledMatch_pred.ScheduledTime + TimeSpan.FromMinutes(BETBUFFER_MINS))     // If next game is within this hour
                        {
                            await SayInChannel(replyChannel, $"{team_pred} is currently playing! ({nextScheduledMatch_pred}) " +
                                               $"Wait until afer the current match to make a prediction.");
                        }
                        else
                        {
                            LCSTeam loser;
                            if (nextScheduledMatch_pred.Team1.Equals(team_pred))
                            {
                                loser = nextScheduledMatch_pred.Team2;
                            }
                            else
                            {
                                loser = nextScheduledMatch_pred.Team1;
                            }

                            // Update existing bets
                            bool updatedPred = false;
                            for (int i = 0; i < Predictions.Count; i++)
                            {
                                if (Predictions[i].DiscordID == discordId)                                             // Of my predictions...
                                {
                                    if (Predictions[i].Victor.Equals(team_pred) && Predictions[i].Loser.Equals(loser)) // Predicting same victory combo
                                    {
                                        await SayInChannel(replyChannel, $"You already predicted that {Predictions[i].Victor} will beat {Predictions[i].Loser} ({nextScheduledMatch_pred})");

                                        updatedPred = true;
                                        break;
                                    }
                                    else if (Predictions[i].Loser.Equals(team_pred) && Predictions[i].Victor.Equals(loser)) // Betting on opposite victory combo
                                    {
                                        Predictions[i] = new Prediction(team_pred, loser, discordId);                       // Create new Bet
                                        await SayInChannel(replyChannel, $"Prediction changed: {Predictions[i].Victor} will beat {Predictions[i].Loser} ({nextScheduledMatch_pred})");

                                        updatedPred = true;
                                        break;
                                    }
                                }
                            }

                            if (!updatedPred)     // Create new bet if no bets were modified
                            {
                                Prediction pred = new Prediction(team_pred, loser, discordId);
                                Predictions.Add(pred);
                                await SayInChannel(replyChannel, $"Prediction made: {pred.Victor} will beat {pred.Loser} ({nextScheduledMatch_pred.ScheduledTime:ddd M/d h:mm tt})");
                            }
                        }
                    }
                }
                break;

            case "placebet":
            case "makebet":
            case "bet":
                // Parse and verify arguments
                if (args.Count() != 2)
                {
                    await SayInChannel(replyChannel, "Usage: !bet <Team> <Wager>");

                    break;
                }
                decimal wager;
                int     argWagerIndex = 0;
                if (!decimal.TryParse(args[argWagerIndex].Trim('$'), out wager))
                {
                    argWagerIndex = 1;
                    if (!decimal.TryParse(args[argWagerIndex].Trim('$'), out wager))
                    {
                        await SayInChannel(replyChannel, "Please enter an amount of money. (!bet <Team> <Wager>)");

                        break;
                    }
                }
                if (wager <= 0)
                {
                    await SayInChannel(replyChannel, "Wager must be greater than $0.");

                    break;
                }
                int     argTeamIndex = argWagerIndex == 0 ? 1 : 0;
                LCSTeam team         = LCSTeam.ParseTeam(args[argTeamIndex]);
                if (team.ID == LCSTeam.TeamID.Unknown)
                {
                    await SayInChannel(replyChannel, $"Unknown LCS team '{args[argTeamIndex]}'");

                    break;
                }
                // Get match timing
                var nextScheduledMatch = Schedule.GetNextMatchForTeam(team);
                if (nextScheduledMatch == null)
                {
                    await SayInChannel(replyChannel, $"Team {team} has no games left in the season.");
                }
                else if (DateTime.Now > nextScheduledMatch.ScheduledTime + TimeSpan.FromMinutes(BETBUFFER_MINS))     // If next game is within this hour
                {
                    await SayInChannel(replyChannel, $"{team} is currently playing! ({nextScheduledMatch}) " +
                                       $"Wait until afer the current match to place a bet.");
                }
                else     // Timing looks good
                {
                    LCSTeam loser;
                    if (nextScheduledMatch.Team1.Equals(team))
                    {
                        loser = nextScheduledMatch.Team2;
                    }
                    else
                    {
                        loser = nextScheduledMatch.Team1;
                    }

                    // Update existing bets
                    bool updatedBet = false;
                    for (int i = 0; i < Bets.Count; i++)
                    {
                        if (Bets[i].DiscordID == discordId)                                 // Of my bets...
                        {
                            if (Bets[i].Victor.Equals(team) && Bets[i].Loser.Equals(loser)) // Betting on same victory combo
                            {
                                if (Bets[i].Wager != wager)                                 // Change wager for same victory combo
                                {
                                    if (Scoreboard[discordId].Money + Bets[i].Wager - wager < 0)
                                    {
                                        await SayInChannel(replyChannel, $"You can't change your bet by that much. You have {Scoreboard[discordId].Money:c}.");

                                        updatedBet = true;
                                        break;
                                    }
                                    else
                                    {
                                        Scoreboard[discordId].Money += Bets[i].Wager - wager;     // Adjust player money to match wager change
                                        Bets[i] = new Bet(team, loser, wager, discordId);
                                        await SayInChannel(replyChannel, $"Bet changed: {Bets[i].Wager:c} on {Bets[i].Victor} beating {Bets[i].Loser} ({nextScheduledMatch.ScheduledTime:ddd M/d h:mm tt})");

                                        updatedBet = true;
                                        Scoreboard.SaveToFile(SavePath);
                                        break;
                                    }
                                }
                                else     // Same wager and victory combo
                                {
                                    await SayInChannel(replyChannel, $"You already bet {Bets[i].Wager:c} on {Bets[i].Victor} (vs {Bets[i].Loser} {nextScheduledMatch.ScheduledTime:ddd M/d h:mm tt})");

                                    updatedBet = true;
                                    break;
                                }
                            }
                            else if (Bets[i].Loser.Equals(team) && Bets[i].Victor.Equals(loser))     // Betting on opposite victory combo
                            {
                                if (Scoreboard[discordId].Money + Bets[i].Wager - wager < 0)
                                {
                                    await SayInChannel(replyChannel, $"You can't change your bet to that. You have {Scoreboard[discordId].Money:c}.");

                                    updatedBet = true;
                                    break;
                                }
                                else
                                {
                                    Scoreboard[discordId].Money += Bets[i].Wager - wager; // Adjust player money to match wager change
                                    Bets[i] = new Bet(team, loser, wager, discordId);     // Create new Bet
                                    await SayInChannel(replyChannel, $"Bet changed: {Bets[i].Wager:c} on {Bets[i].Victor} beating {Bets[i].Loser} ({nextScheduledMatch.ScheduledTime:ddd M/d h:mm tt})");

                                    updatedBet = true;
                                    Scoreboard.SaveToFile(SavePath);
                                    break;
                                }
                            }
                        }
                    }

                    if (!updatedBet)     // Create new bet if no bets were modified
                    {
                        if (Scoreboard[discordId].Money - wager < 0)
                        {
                            await SayInChannel(replyChannel, $"You can't bet that much. You have {Scoreboard[discordId].Money:c}.");

                            updatedBet = true;
                            break;
                        }
                        else
                        {
                            Bet bet = new Bet(team, loser, wager, discordId);
                            Bets.Add(bet);
                            Scoreboard.TakeMoney(discordId, wager);
                            Scoreboard[discordId].BetCount += 1;
                            Scoreboard.SaveToFile(SavePath);
                            await SayInChannel(replyChannel, $"Bet placed: {wager:c} on {team} beating {loser} ({nextScheduledMatch.ScheduledTime:ddd M/d h:mm tt})");
                        }
                    }
                }
                break;
            }
        }