Пример #1
0
        public async Task UpdateTeamScoresAsync(bool win, HashSet <ulong> userIds)
        {
            var competition = Service.GetOrCreateCompetition(Context.Guild.Id);
            var updates     = new List <(Player, int, Rank, RankChangeState, Rank)>();

            var embed = new EmbedBuilder
            {
                Title = (win ? "Win" : "Lose") + $" Manual Game: #{competition.ManualGameCounter + 1}",
                Color = win ? Color.Green : Color.Red,
            };
            var sb = new StringBuilder();

            foreach (var userId in userIds)
            {
                var player = Service.GetPlayer(Context.Guild.Id, userId);
                if (player == null)
                {
                    continue;
                }

                //This represents the current user's rank
                var maxRank = competition.MaxRank(player.Points);

                int             updateVal;
                RankChangeState state   = RankChangeState.None;
                Rank            newRank = null;

                if (win)
                {
                    updateVal = maxRank?.WinModifier ?? competition.DefaultWinModifier;
                    player.SetPoints(competition, player.Points + updateVal);
                    player.Wins++;
                    newRank = competition.MaxRank(player.Points);
                    if (newRank != null)
                    {
                        if (maxRank == null)
                        {
                            state = RankChangeState.RankUp;
                        }
                        else if (newRank.RoleId != maxRank.RoleId)
                        {
                            state = RankChangeState.RankUp;
                        }
                    }
                }
                else
                {
                    //Loss modifier is always positive so subtract it
                    updateVal = maxRank?.LossModifier ?? competition.DefaultLossModifier;
                    player.SetPoints(competition, player.Points - updateVal);
                    player.Losses++;
                    //Set the update value to a negative value for returning purposes.
                    updateVal = -updateVal;

                    if (maxRank != null)
                    {
                        if (player.Points < maxRank.Points)
                        {
                            state   = RankChangeState.DeRank;
                            newRank = competition.MaxRank(player.Points);
                        }
                    }
                }

                updates.Add((player, updateVal, maxRank, state, newRank));

                //TODO: Rank checking?
                //I forget what this means honestly
                Service.SavePlayer(player);

                //Ignore user updates if they aren't found in the server.
                var gUser = Context.Guild.GetUser(userId);
                if (gUser == null)
                {
                    continue;
                }

                await Service.UpdateUserAsync(competition, player, gUser);

                var rankUpdate = "";
                if (maxRank != null || newRank != null)
                {
                    var oldRoleMention = maxRank == null ? "N/A" : MentionUtils.MentionRole(maxRank.RoleId);
                    var newRoleMention = newRank == null ? "N/A" : MentionUtils.MentionRole(newRank.RoleId);
                    rankUpdate = $" Rank: {oldRoleMention} => {newRoleMention}";
                }

                sb.AppendLine($"{gUser.Mention} Points: {player.Points} {(win ? "Added:" : "Removed:")} {updateVal}{rankUpdate}");
            }

            //Update counter and save new competition config
            competition.ManualGameCounter++;
            Service.SaveCompetition(competition);

            //Create new game info
            var game = new ManualGameResult(competition.ManualGameCounter, Context.Guild.Id);

            game.Submitter    = Context.User.Id;
            game.GameState    = win ? ManualGameResult.ManualGameState.Win : ManualGameResult.ManualGameState.Lose;
            game.ScoreUpdates = updates.ToDictionary(x => x.Item1.UserId, x => x.Item2);
            embed.Description = sb.ToString();
            Service.SaveManualGame(game);
            await ReplyAsync(embed);
        }
Пример #2
0
        public virtual async Task UpdateTeamScoresAsync(bool win, HashSet <ulong> userIds)
        {
            using (var db = new Database())
            {
                var competition = db.GetOrCreateCompetition(Context.Guild.Id);
                var updates     = new List <(Player, int, Rank, RankChangeState, Rank)>();
                var ranks       = db.Ranks.Where(x => x.GuildId == Context.Guild.Id).ToArray();
                var embed       = new EmbedBuilder
                {
                    Title = (win ? "Win" : "Lose") + $" Manual Game: #{competition.ManualGameCounter + 1}",
                    Color = win ? Color.Green : Color.Red,
                };

                var sb = new StringBuilder();
                foreach (var userId in userIds)
                {
                    var player = db.Players.Find(Context.Guild.Id, userId);
                    if (player == null)
                    {
                        continue;
                    }

                    //This represents the current user's rank
                    var maxRank = ranks.Where(x => x.Points <= player.Points).OrderByDescending(x => x.Points).FirstOrDefault();

                    int             updateVal;
                    RankChangeState state   = RankChangeState.None;
                    Rank            newRank = null;

                    if (win)
                    {
                        updateVal      = maxRank?.WinModifier ?? competition.DefaultWinModifier;
                        player.Points += updateVal;
                        player.Wins++;
                        newRank = ranks.Where(x => x.Points <= player.Points).OrderByDescending(x => x.Points).FirstOrDefault();
                        if (newRank != null)
                        {
                            if (maxRank == null)
                            {
                                state = RankChangeState.RankUp;
                            }
                            else if (newRank.RoleId != maxRank.RoleId)
                            {
                                state = RankChangeState.RankUp;
                            }
                        }
                    }
                    else
                    {
                        //Loss modifier is always positive so subtract it
                        updateVal = maxRank?.LossModifier ?? competition.DefaultLossModifier;

                        player.Points -= updateVal;
                        if (!competition.AllowNegativeScore && player.Points < 0)
                        {
                            player.Points = 0;
                        }
                        player.Losses++;
                        //Set the update value to a negative value for returning purposes.
                        updateVal = -Math.Abs(updateVal);

                        if (maxRank != null)
                        {
                            if (player.Points < maxRank.Points)
                            {
                                state   = RankChangeState.DeRank;
                                newRank = ranks.Where(x => x.Points <= player.Points).OrderByDescending(x => x.Points).FirstOrDefault();
                            }
                        }
                    }

                    updates.Add((player, updateVal, maxRank, state, newRank));
                    db.Update(player);

                    //Ignore user updates if they aren't found in the server.
                    var gUser = Context.Guild.GetUser(userId);
                    if (gUser == null)
                    {
                        continue;
                    }

                    var _ = Task.Run(async() => await UserService.UpdateUserAsync(competition, player, ranks, gUser));

                    var rankUpdate = "";
                    if (maxRank != null || newRank != null)
                    {
                        var oldRoleMention = maxRank == null ? "N/A" : MentionUtils.MentionRole(maxRank.RoleId);
                        var newRoleMention = newRank == null ? "N/A" : MentionUtils.MentionRole(newRank.RoleId);
                        rankUpdate = $" Rank: {oldRoleMention} => {newRoleMention}";
                    }

                    sb.AppendLine($"{gUser.Mention} Points: {player.Points} {(win ? "Added:" : "Removed:")} {updateVal}{rankUpdate}");
                }

                //Update counter and save new competition config


                //Create new game info
                var vals  = ((IQueryable <ManualGameResult>)db.ManualGameResults).Where(x => x.GuildId == Context.Guild.Id).ToArray();
                var count = vals.Length == 0 ? 0 : vals.Max(x => x.GameId);
                var game  = new ManualGameResult
                {
                    GuildId = Context.Guild.Id,
                    GameId  = count + 1
                };

                competition.ManualGameCounter = game.GameId;
                db.Update(competition);
                game.Submitter = Context.User.Id;
                game.GameState = win ? ManualGameState.Win : ManualGameState.Lose;
                db.ManualGameResults.Add(game);
                db.SaveChanges();
                game = db.ManualGameResults.Where(x => x.GuildId == Context.Guild.Id).OrderByDescending(x => x.GameId).First();

                foreach (var upd in updates)
                {
                    db.ManualGameScoreUpdates.Add(new ManualGameScoreUpdate
                    {
                        GuildId      = Context.Guild.Id,
                        ManualGameId = game.GameId,
                        ModifyAmount = upd.Item2,
                        UserId       = upd.Item1.UserId
                    });
                }

                embed.Description = sb.ToString();
                db.SaveChanges();
                //save scores
                await ReplyAsync(embed);
            }
        }
        //returns a list of userIds and the amount of points they received/lost for the win/loss, and if the user lost/gained a rank
        //UserId, Points added/removed, rank before, rank modify state, rank after
        /// <summary>
        /// Retrieves and updates player scores/wins
        /// </summary>
        /// <returns>
        /// A list containing a value tuple with the
        /// Player object
        /// Amount of points received/lost
        /// The player's current rank
        /// The player's rank change state (rank up, derank, none)
        /// The players new rank (if changed)
        /// </returns>
        public List <(Player, int, Rank, RankChangeState, Rank)> UpdateTeamScoresAsync(Competition competition, Lobby lobby, GameResult game, Rank[] ranks, bool win, HashSet <ulong> userIds, Database db)
        {
            var updates = new List <(Player, int, Rank, RankChangeState, Rank)>();

            foreach (var userId in userIds)
            {
                var player = db.Players.Find(competition.GuildId, userId);
                if (player == null)
                {
                    continue;
                }

                //This represents the current user's rank
                var maxRank = ranks.Where(x => x.Points < player.Points).OrderByDescending(x => x.Points).FirstOrDefault();

                int             updateVal;
                RankChangeState state   = RankChangeState.None;
                Rank            newRank = null;

                if (win)
                {
                    updateVal = (int)((maxRank?.WinModifier ?? competition.DefaultWinModifier) * lobby.LobbyMultiplier);
                    if (lobby.HighLimit != null)
                    {
                        if (player.Points > lobby.HighLimit)
                        {
                            updateVal = (int)(updateVal * lobby.ReductionPercent);
                        }
                    }
                    player.Points += updateVal;
                    player.Wins++;
                    newRank = ranks.Where(x => x.Points <= player.Points).OrderByDescending(x => x.Points).FirstOrDefault();
                    if (newRank != null)
                    {
                        if (maxRank == null)
                        {
                            state = RankChangeState.RankUp;
                        }
                        else if (newRank.RoleId != maxRank.RoleId)
                        {
                            state = RankChangeState.RankUp;
                        }
                    }
                }
                else
                {
                    //Loss modifiers are always positive values that are to be subtracted
                    updateVal = maxRank?.LossModifier ?? competition.DefaultLossModifier;
                    if (lobby.MultiplyLossValue)
                    {
                        updateVal = (int)(updateVal * lobby.LobbyMultiplier);
                    }

                    player.Points -= updateVal;
                    if (!competition.AllowNegativeScore && player.Points < 0)
                    {
                        player.Points = 0;
                    }
                    player.Losses++;
                    //Set the update value to a negative value for returning purposes.
                    updateVal = -Math.Abs(updateVal);

                    if (maxRank != null)
                    {
                        if (player.Points < maxRank.Points)
                        {
                            state   = RankChangeState.DeRank;
                            newRank = ranks.Where(x => x.Points <= player.Points).OrderByDescending(x => x.Points).FirstOrDefault();
                        }
                    }
                }

                updates.Add((player, updateVal, maxRank, state, newRank));
                var oldUpdate = db.ScoreUpdates.FirstOrDefault(x => x.ChannelId == lobby.ChannelId && x.GameNumber == game.GameId && x.UserId == userId);
                if (oldUpdate == null)
                {
                    var update = new ScoreUpdate
                    {
                        GuildId      = competition.GuildId,
                        ChannelId    = game.LobbyId,
                        UserId       = userId,
                        GameNumber   = game.GameId,
                        ModifyAmount = updateVal
                    };
                    db.ScoreUpdates.Add(update);
                }
                else
                {
                    oldUpdate.ModifyAmount = updateVal;
                    db.ScoreUpdates.Update(oldUpdate);
                }

                db.Update(player);
            }
            db.SaveChanges();
            return(updates);
        }