BF2Statistics.Web.Bf2Stats.RankCalculator.GetNextRanks C# (CSharp) Method

GetNextRanks() public static method

Generates the next Count ranks that can currently be obtained by the player
public static GetNextRanks ( int Score, int Rank, int>.Dictionary Awards, int Count = 3 ) : List
Score int The players current score
Rank int The players current rank ID
Awards int>.Dictionary All the players earned awards
Count int The number of next ranks to display
return List
        public static List<Rank> GetNextRanks(int Score, int Rank, Dictionary<string, int> Awards, int Count = 3)
        {
            // do 1 rank at a time until we get 3 go's
            List<Rank> NextXRanks = new List<Rank>();
            int Avail = 21 - Rank; // Available promotions left
            StringBuilder Desc = new StringBuilder();

            // Make sure we dont get an index out of range exception
            if (Avail < Count) Count = Avail;

            // Loop through each promotion
            for (int i = 0; i < Count; i++)
            {
                // Update rank
                if (NextXRanks.Count > 0)
                    Rank = NextXRanks.Last().Id;

                // Generate a list of ranks we can jump to based on our current rank
                List<Rank> NextPromoRanks = GetNextRankUps(Rank, Awards);
                if (NextPromoRanks.Count == 0)
                    break;

                // Defines if we added a rank for the next promotion
                bool AddedARank = false;

                // We need to reverse the next rank array, so highest possible ranks are first, and
                // then we work our way down until we are just +1 rank
                foreach (Rank Rnk in NextPromoRanks.Reverse<Rank>())
                {
                    // First we loop through the required awards (if any), and see if we
                    // have the required awards and level to meet the promotion requirement
                    bool MeetsAwardReqs = true;
                    if (Rnk.ReqAwards.Count > 0)
                    {
                        foreach (KeyValuePair<string, int> Awd in Rnk.ReqAwards)
                        {
                            if (!Awards.ContainsKey(Awd.Key) || Awards[Awd.Key] < Awd.Value)
                            {
                                MeetsAwardReqs = false;
                                Rnk.MissingAwards.Add(Awd.Key, Awd.Value);
                            }
                        }
                    }

                    // If we meet the requirement for this rank, add it
                    if (MeetsAwardReqs)
                    {
                        // Set missing awards description
                        if (Desc.Length != 0)
                        {
                            Rnk.MissingDesc = Desc.ToString();
                            Desc.Clear();
                        }

                        NextXRanks.Add(Rnk);
                        AddedARank = true;
                        break;
                    }
                    else
                    {
                        // If we have multiple ranks for next promotion, and we havent cycled through all of them
                        if (NextPromoRanks.Count > 1 && Rnk != NextPromoRanks[0])
                        {
                            Desc.Clear();
                            Desc.Append(GenerateMissingDesc(Rnk, true));
                        }
                        else
                            Rnk.MissingDesc = GenerateMissingDesc(Rnk, false);
                    }
                }

                // Make sure we add at least the next rank, even if we dont qualify
                if (!AddedARank)
                {
                    NextXRanks.Add(NextPromoRanks[0]);
                }
            }

            return NextXRanks;
        }

Usage Example

        private void ShowStats()
        {
            // Check cache
            if (!base.CacheFileExpired(Pid.ToString(), 30))
            {
                base.SendCachedResponse(Pid.ToString());
                return;
            }

            // Load our Model
            PlayerModel Model = new PlayerModel(Client);

            Model.Player         = Rows[0];
            Model.SearchBarValue = Pid.ToString();

            // Setup player variables
            int    PlayerKills = Int32.Parse(Model.Player["kills"].ToString());
            double AcctsFor    = 0;
            int    j           = 0;

            // My Leaderboard stuff
            Cookie C = Client.Request.Request.Cookies["leaderboard"] ?? new Cookie("leaderboard", "");

            Model.OnMyLeaderboard = C.Value.Contains(Pid.ToString());

            #region ArmyData
            // Fetch army data
            Rows = Database.Query("SELECT * FROM army WHERE id=@P0", Pid);
            foreach (KeyValuePair <int, string> Army in Bf2StatsData.Armies)
            {
                int Wins   = Int32.Parse(Rows[0]["win" + Army.Key].ToString());
                int Losses = Int32.Parse(Rows[0]["loss" + Army.Key].ToString());
                Model.ArmyData.Add(new ArmyMapStat
                {
                    Id     = Army.Key,
                    Time   = Int32.Parse(Rows[0]["time" + Army.Key].ToString()),
                    Wins   = Wins,
                    Losses = Losses,
                    Best   = Int32.Parse(Rows[0]["best" + Army.Key].ToString()),
                });

                Model.ArmySummary.TotalWins   += Wins;
                Model.ArmySummary.TotalLosses += Losses;
                Model.ArmySummary.TotalTime   += Model.ArmyData[j].Time;
                Model.ArmySummary.TotalBest   += Model.ArmyData[j].Best;
                j++;
            }
            #endregion ArmyData

            #region MapData
            // Fetch Map Data
            j    = 0;
            Rows = Database.Query("SELECT * FROM maps WHERE id=@P0 ORDER BY mapid", Pid);
            foreach (Dictionary <string, object> Row in Rows)
            {
                // Do we support this map id?
                if (!Bf2StatsData.Maps.Keys.Contains(Int32.Parse(Row["mapid"].ToString())))
                {
                    continue;
                }

                int Wins   = Int32.Parse(Row["win"].ToString());
                int Losses = Int32.Parse(Row["loss"].ToString());
                Model.MapData.Add(new ArmyMapStat
                {
                    Id     = Int32.Parse(Row["mapid"].ToString()),
                    Time   = Int32.Parse(Row["time"].ToString()),
                    Wins   = Wins,
                    Losses = Losses,
                    Best   = Int32.Parse(Row["best"].ToString()),
                });

                Model.MapSummary.TotalWins   += Wins;
                Model.MapSummary.TotalLosses += Losses;
                Model.MapSummary.TotalTime   += Model.MapData[j].Time;
                Model.MapSummary.TotalBest   += Model.MapData[j].Best;
                j++;
            }
            #endregion MapData

            #region TheaterData
            // Do Theater Data
            foreach (KeyValuePair <string, int[]> t in Bf2StatsData.TheatreMapIds)
            {
                j = 0;
                string inn = String.Join(",", t.Value);
                Rows = Database.Query(
                    "SELECT COALESCE(sum(time), 0) as time, COALESCE(sum(win), 0) as win, COALESCE(sum(loss), 0) as loss, COALESCE(max(best), 0) as best "
                    + "FROM maps WHERE mapid IN (" + inn + ") AND id=@P0", Pid
                    );

                //
                Model.TheaterData.Add(new TheaterStat
                {
                    Name   = t.Key,
                    Time   = Int32.Parse(Rows[0]["time"].ToString()),
                    Wins   = Int32.Parse(Rows[0]["win"].ToString()),
                    Losses = Int32.Parse(Rows[0]["loss"].ToString()),
                    Best   = Int32.Parse(Rows[0]["best"].ToString()),
                });
            }
            #endregion TheaterData

            #region VehicleData
            // Fetch Vehicle Data
            Rows = Database.Query("SELECT * FROM vehicles WHERE id=@P0", Pid);
            for (int i = 0; i < 7; i++)
            {
                int Kills     = Int32.Parse(Rows[0]["kills" + i].ToString());
                int Deaths    = Int32.Parse(Rows[0]["deaths" + i].ToString());
                int RoadKills = Int32.Parse(Rows[0]["rk" + i].ToString());
                Model.VehicleData.Add(new ObjectStat
                {
                    Time         = Int32.Parse(Rows[0]["time" + i].ToString()),
                    Kills        = Kills,
                    Deaths       = Deaths,
                    RoadKills    = RoadKills,
                    KillsAcctFor = (PlayerKills == 0 || Kills == 0) ? 0.00 : Math.Round(100 * ((double)(RoadKills + Kills) / PlayerKills), 2)
                });

                Model.VehicleSummary.TotalKills     += Kills;
                Model.VehicleSummary.TotalDeaths    += Deaths;
                Model.VehicleSummary.TotalTime      += Model.VehicleData[i].Time;
                Model.VehicleSummary.TotalRoadKills += Model.VehicleData[i].RoadKills;
                AcctsFor += Model.VehicleData[i].KillsAcctFor;
            }

            // Add para time
            Model.VehicleData.Add(new ObjectStat {
                Time = Int32.Parse(Rows[0]["timepara"].ToString())
            });
            Model.VehicleSummary.KillsAcctFor = (AcctsFor > 0) ? Math.Round(AcctsFor / 7, 2) : 0.00;
            #endregion VehicleData

            #region XpackTime
            // Do Expansion time
            foreach (KeyValuePair <string, List <int> > t in Bf2StatsData.ModMapIds)
            {
                if (t.Value.Count > 0)
                {
                    string inn = String.Join(",", t.Value);
                    Rows = Database.Query("SELECT COALESCE(sum(time), 0) as time FROM maps WHERE mapid IN (" + inn + ") AND id=@P0", Pid);
                    if (Model.ExpackTime.ContainsKey(t.Key))
                    {
                        Model.ExpackTime[t.Key] = Int32.Parse(Rows[0]["time"].ToString());
                    }
                    else
                    {
                        Model.ExpackTime.Add(t.Key, Int32.Parse(Rows[0]["time"].ToString()));
                    }
                }
            }
            #endregion XpackTime

            #region KitData
            // Fetch Kit Data
            AcctsFor = 0;
            Rows     = Database.Query("SELECT * FROM kits WHERE id=@P0", Pid);
            for (int i = 0; i < 7; i++)
            {
                int Kills  = Int32.Parse(Rows[0]["kills" + i].ToString());
                int Deaths = Int32.Parse(Rows[0]["deaths" + i].ToString());
                Model.KitData.Add(new ObjectStat
                {
                    Time         = Int32.Parse(Rows[0]["time" + i].ToString()),
                    Kills        = Kills,
                    Deaths       = Deaths,
                    KillsAcctFor = (PlayerKills == 0 || Kills == 0) ? 0.00 : Math.Round(100 * ((double)Kills / PlayerKills), 2)
                });

                Model.KitSummary.TotalKills  += Kills;
                Model.KitSummary.TotalDeaths += Deaths;
                Model.KitSummary.TotalTime   += Model.KitData[i].Time;
                AcctsFor += Model.KitData[i].KillsAcctFor;
            }
            Model.KitSummary.KillsAcctFor = (AcctsFor > 0) ? Math.Round(AcctsFor / 7, 2) : 0.00;
            #endregion KitData

            #region WeaponData
            // Fetch weapon Data
            AcctsFor = 0;
            double AcctsFor2 = 0;
            Rows = Database.Query("SELECT * FROM weapons WHERE id=@P0", Pid);
            for (int i = 0; i < 15; i++)
            {
                if (i < 9)
                {
                    int Kills  = Int32.Parse(Rows[0]["kills" + i].ToString());
                    int Deaths = Int32.Parse(Rows[0]["deaths" + i].ToString());
                    int Hits   = Int32.Parse(Rows[0]["hit" + i].ToString());
                    int Fired  = Int32.Parse(Rows[0]["fired" + i].ToString());
                    Model.WeaponData.Add(new WeaponStat
                    {
                        Time         = Int32.Parse(Rows[0]["time" + i].ToString()),
                        Kills        = Kills,
                        Deaths       = Deaths,
                        Hits         = Hits,
                        Fired        = Fired,
                        KillsAcctFor = (PlayerKills == 0 || Kills == 0) ? 0.00 : Math.Round(100 * ((double)Kills / PlayerKills), 2)
                    });
                }
                else
                {
                    string Pfx    = GetWeaponTblPrefix(i);
                    int    Kills  = Int32.Parse(Rows[0][Pfx + "kills"].ToString());
                    int    Deaths = Int32.Parse(Rows[0][Pfx + "deaths"].ToString());
                    int    Hits   = Int32.Parse(Rows[0][Pfx + "hit"].ToString());
                    int    Fired  = Int32.Parse(Rows[0][Pfx + "fired"].ToString());
                    Model.WeaponData.Add(new WeaponStat
                    {
                        Time         = Int32.Parse(Rows[0][Pfx + "time"].ToString()),
                        Kills        = Kills,
                        Deaths       = Deaths,
                        Hits         = Hits,
                        Fired        = Fired,
                        KillsAcctFor = (PlayerKills == 0 || Kills == 0) ? 0.00 : Math.Round(100 * ((double)Kills / PlayerKills), 2)
                    });
                }
            }

            Model.WeaponData.Add(new WeaponStat
            {
                Time  = Int32.Parse(Rows[0]["tacticaltime"].ToString()),
                Fired = Int32.Parse(Rows[0]["tacticaldeployed"].ToString())
            });

            Model.WeaponData.Add(new WeaponStat
            {
                Time   = Int32.Parse(Rows[0]["grapplinghooktime"].ToString()),
                Deaths = Int32.Parse(Rows[0]["grapplinghookdeaths"].ToString()),
                Fired  = Int32.Parse(Rows[0]["grapplinghookdeployed"].ToString())
            });

            Model.WeaponData.Add(new WeaponStat
            {
                Time   = Int32.Parse(Rows[0]["ziplinetime"].ToString()),
                Deaths = Int32.Parse(Rows[0]["ziplinedeaths"].ToString()),
                Fired  = Int32.Parse(Rows[0]["ziplinedeployed"].ToString())
            });

            for (int i = 0; i < 17; i++)
            {
                Model.WeaponSummary.TotalKills  += Model.WeaponData[i].Kills;
                Model.WeaponSummary.TotalDeaths += Model.WeaponData[i].Deaths;
                Model.WeaponSummary.TotalTime   += Model.WeaponData[i].Time;
                Model.WeaponSummary.TotalHits   += Model.WeaponData[i].Hits;
                Model.WeaponSummary.TotalFired  += Model.WeaponData[i].Fired;
                AcctsFor += Model.WeaponData[i].KillsAcctFor;

                if (i > 8)
                {
                    Model.EquipmentSummary.TotalKills  += Model.WeaponData[i].Kills;
                    Model.EquipmentSummary.TotalDeaths += Model.WeaponData[i].Deaths;
                    Model.EquipmentSummary.TotalTime   += Model.WeaponData[i].Time;
                    Model.EquipmentSummary.TotalHits   += Model.WeaponData[i].Hits;
                    Model.EquipmentSummary.TotalFired  += Model.WeaponData[i].Fired;
                    AcctsFor2 += Model.WeaponData[i].KillsAcctFor;
                }
            }
            Model.WeaponSummary.KillsAcctFor    = (AcctsFor > 0) ? Math.Round(AcctsFor / 15, 2) : 0.00;
            Model.EquipmentSummary.KillsAcctFor = (AcctsFor > 0) ? Math.Round(AcctsFor / 6, 2) : 0.00;

            // Extra weapon data DEFIB
            Model.WeaponData2.Add(Model.WeaponData[13]);

            // Extra Weapon data Explosives
            Model.WeaponData2.Add(new WeaponStat
            {
                Time         = Model.WeaponData[10].Time + Model.WeaponData[11].Time + Model.WeaponData[14].Time,
                Kills        = Model.WeaponData[10].Kills + Model.WeaponData[11].Kills + Model.WeaponData[14].Kills,
                Deaths       = Model.WeaponData[10].Deaths + Model.WeaponData[11].Deaths + Model.WeaponData[14].Deaths,
                Hits         = Model.WeaponData[10].Hits + Model.WeaponData[11].Hits + Model.WeaponData[14].Hits,
                Fired        = Model.WeaponData[10].Fired + Model.WeaponData[11].Fired + Model.WeaponData[14].Fired,
                KillsAcctFor = Model.WeaponData[10].KillsAcctFor + Model.WeaponData[11].KillsAcctFor + Model.WeaponData[14].KillsAcctFor
            });

            // Extra weapon data Grenade
            Model.WeaponData2.Add(Model.WeaponData[12]);

            #endregion WeaponData

            #region Favorites

            // Add Favorites
            Model.Favorites.Add("army", (from x in Model.ArmyData orderby x.Time select Model.ArmyData.IndexOf(x)).Last());
            Model.Favorites.Add("map", (Model.MapData.Count == 0)
                ? -1
                : (from x in Model.MapData orderby x.Time select Model.MapData.IndexOf(x)).Last());
            Model.Favorites.Add("theater", (from x in Model.TheaterData orderby x.Time select Model.TheaterData.IndexOf(x)).Last());
            Model.Favorites.Add("vehicle", (from x in Model.VehicleData orderby x.Time select Model.VehicleData.IndexOf(x)).Last());
            Model.Favorites.Add("kit", (from x in Model.KitData orderby x.Time select Model.KitData.IndexOf(x)).Last());
            Model.Favorites.Add("weapon", (from x in Model.WeaponData orderby x.Time select Model.WeaponData.IndexOf(x)).Last());
            Model.Favorites.Add("equipment",
                                (
                                    from x in Model.WeaponData
                                    orderby x.Time
                                    let index = Model.WeaponData.IndexOf(x)
                                                where index > 8
                                                select index
                                ).Last());
            Model.FavoriteMapId = Model.Favorites["map"] >= 0 ? Model.MapData[Model.Favorites["map"]].Id : -1;

            #endregion

            #region TopEnemy and Victim
            // Get top enemy's
            Rows = Database.Query(
                "SELECT attacker, count, t.name AS name, t.rank AS rank FROM kills JOIN player AS t WHERE t.id = attacker AND victim = @P0 ORDER BY count DESC LIMIT 11",
                Pid
                );
            if (Rows.Count > 0)
            {
                Model.TopEnemies.Add(new Player
                {
                    Pid   = Int32.Parse(Rows[0]["attacker"].ToString()),
                    Name  = Rows[0]["name"].ToString(),
                    Rank  = Int32.Parse(Rows[0]["rank"].ToString()),
                    Count = Int32.Parse(Rows[0]["count"].ToString()),
                });

                if (Rows.Count > 1)
                {
                    for (int i = 1; i < Rows.Count; i++)
                    {
                        Model.TopEnemies.Add(new Player
                        {
                            Pid   = Int32.Parse(Rows[i]["attacker"].ToString()),
                            Name  = Rows[i]["name"].ToString(),
                            Rank  = Int32.Parse(Rows[i]["rank"].ToString()),
                            Count = Int32.Parse(Rows[i]["count"].ToString()),
                        });
                    }
                }
            }

            // Get top victims's
            Rows = Database.Query(
                "SELECT victim, count, t.name AS name, t.rank AS rank FROM kills JOIN player AS t WHERE t.id = victim AND attacker = @P0 ORDER BY count DESC LIMIT 11",
                Pid
                );
            if (Rows.Count > 0)
            {
                Model.TopVictims.Add(new Player
                {
                    Pid   = Int32.Parse(Rows[0]["victim"].ToString()),
                    Name  = Rows[0]["name"].ToString(),
                    Rank  = Int32.Parse(Rows[0]["rank"].ToString()),
                    Count = Int32.Parse(Rows[0]["count"].ToString()),
                });

                if (Rows.Count > 1)
                {
                    for (int i = 1; i < Rows.Count; i++)
                    {
                        Model.TopVictims.Add(new Player
                        {
                            Pid   = Int32.Parse(Rows[i]["victim"].ToString()),
                            Name  = Rows[i]["name"].ToString(),
                            Rank  = Int32.Parse(Rows[i]["rank"].ToString()),
                            Count = Int32.Parse(Rows[i]["count"].ToString()),
                        });
                    }
                }
            }

            #endregion TopEnemy and Victim

            #region Unlocks
            j    = 0;
            Rows = Database.Query("SELECT kit, state FROM unlocks WHERE id=@P0 ORDER BY kit ASC", Pid);
            if (Rows.Count > 0)
            {
                foreach (Dictionary <string, object> Row in Rows)
                {
                    Model.PlayerUnlocks[j] = new WeaponUnlock
                    {
                        Id    = Int32.Parse(Row["kit"].ToString()),
                        Name  = Bf2Constants.Unlocks[Row["kit"].ToString()],
                        State = Row["state"].ToString()
                    };
                    j++;
                }
            }
            else
            {
                // Normal unlocks
                for (int i = 11; i < 100; i += 11)
                {
                    // 88 and above are Special Forces unlocks, and wont display at all if the base unlocks are not earned
                    Model.PlayerUnlocks[j] = new WeaponUnlock
                    {
                        Id    = i,
                        Name  = Bf2Constants.Unlocks[i.ToString()],
                        State = "n"
                    };
                    j++;
                }

                // Sf Unlocks, Dont display these because thats how Gamespy does it
                for (int i = 111; i < 556; i += 111)
                {
                    Model.PlayerUnlocks[j] = new WeaponUnlock
                    {
                        Id    = i,
                        Name  = Bf2Constants.Unlocks[i.ToString()],
                        State = "n"
                    };
                    j++;
                }
            }
            #endregion Unlocks

            #region Badges
            // Fetch player badges
            foreach (KeyValuePair <string, string> Awd in StatsConstants.Badges)
            {
                int          AwdId  = Int32.Parse(Awd.Key);
                List <Award> Badges = new List <Award>(4);
                for (int i = 0; i < 4; i++)
                {
                    Badges.Add(new Award {
                        Id = AwdId
                    });
                }

                Rows = Database.Query("SELECT * FROM awards WHERE id=@P0 AND awd=@P1 ORDER BY level ASC", Pid, AwdId);
                if (Rows.Count > 0)
                {
                    int max      = Rows.Count - 1;
                    int Maxlevel = Int32.Parse(Rows[max]["level"].ToString());
                    Badges[0] = new Award
                    {
                        Id     = AwdId,
                        Level  = Maxlevel,
                        Earned = Int32.Parse(Rows[max]["earned"].ToString())
                    };

                    for (int i = 1; i < 4; i++)
                    {
                        if (Rows.Count >= i)
                        {
                            Badges[i] = new Award
                            {
                                Id     = AwdId,
                                Level  = Int32.Parse(Rows[i - 1]["level"].ToString()),
                                Earned = Int32.Parse(Rows[i - 1]["earned"].ToString())
                            };
                        }
                    }
                }

                Model.PlayerBadges.Add(Awd.Key, Badges);
            }

            // Fetch player badges
            foreach (KeyValuePair <string, string> Awd in StatsConstants.SfBadges)
            {
                int          AwdId  = Int32.Parse(Awd.Key);
                List <Award> Badges = new List <Award>(4);
                for (int i = 0; i < 4; i++)
                {
                    Badges.Add(new Award {
                        Id = AwdId
                    });
                }

                Rows = Database.Query("SELECT * FROM awards WHERE id=@P0 AND awd=@P1 ORDER BY level ASC", Pid, AwdId);
                if (Rows.Count > 0)
                {
                    int max      = Rows.Count - 1;
                    int Maxlevel = Int32.Parse(Rows[max]["level"].ToString());
                    Badges[0] = new Award
                    {
                        Id     = AwdId,
                        Level  = Maxlevel,
                        Earned = Int32.Parse(Rows[max]["earned"].ToString())
                    };

                    for (int i = 1; i < 4; i++)
                    {
                        if (Rows.Count >= i)
                        {
                            Badges[i] = new Award
                            {
                                Id     = AwdId,
                                Level  = Int32.Parse(Rows[i - 1]["level"].ToString()),
                                Earned = Int32.Parse(Rows[i - 1]["earned"].ToString())
                            };
                        }
                    }
                }

                Model.PlayerSFBadges.Add(Awd.Key, Badges);
            }
            #endregion Badges

            #region Medals

            // Fetch player medals
            foreach (KeyValuePair <string, string> Awd in StatsConstants.Medals)
            {
                int AwdId = Int32.Parse(Awd.Key);
                Rows = Database.Query("SELECT * FROM awards WHERE id=@P0 AND awd=@P1 LIMIT 1", Pid, AwdId);
                if (Rows.Count > 0)
                {
                    Model.PlayerMedals.Add(Awd.Key, new Award
                    {
                        Id     = AwdId,
                        Level  = Int32.Parse(Rows[0]["level"].ToString()),
                        Earned = Int32.Parse(Rows[0]["earned"].ToString()),
                        First  = Int32.Parse(Rows[0]["first"].ToString()),
                    });
                }
                else
                {
                    Model.PlayerMedals.Add(Awd.Key, new Award {
                        Id = AwdId
                    });
                }
            }

            foreach (KeyValuePair <string, string> Awd in StatsConstants.SfMedals)
            {
                int AwdId = Int32.Parse(Awd.Key);
                Rows = Database.Query("SELECT * FROM awards WHERE id=@P0 AND awd=@P1 LIMIT 1", Pid, AwdId);
                if (Rows.Count > 0)
                {
                    Model.PlayerSFMedals.Add(Awd.Key, new Award
                    {
                        Id     = AwdId,
                        Level  = Int32.Parse(Rows[0]["level"].ToString()),
                        Earned = Int32.Parse(Rows[0]["earned"].ToString()),
                        First  = Int32.Parse(Rows[0]["first"].ToString()),
                    });
                }
                else
                {
                    Model.PlayerSFMedals.Add(Awd.Key, new Award {
                        Id = AwdId
                    });
                }
            }

            #endregion Medals

            #region Ribbons

            // Fetch player ribbons
            foreach (KeyValuePair <string, string> Awd in StatsConstants.Ribbons)
            {
                int AwdId = Int32.Parse(Awd.Key);
                Rows = Database.Query("SELECT * FROM awards WHERE id=@P0 AND awd=@P1 LIMIT 1", Pid, AwdId);
                if (Rows.Count > 0)
                {
                    Model.PlayerRibbons.Add(Awd.Key, new Award
                    {
                        Id     = AwdId,
                        Level  = Int32.Parse(Rows[0]["level"].ToString()),
                        Earned = Int32.Parse(Rows[0]["earned"].ToString()),
                        First  = Int32.Parse(Rows[0]["first"].ToString()),
                    });
                }
                else
                {
                    Model.PlayerRibbons.Add(Awd.Key, new Award {
                        Id = AwdId
                    });
                }
            }

            // Fetch SF Ribbons
            foreach (KeyValuePair <string, string> Awd in StatsConstants.SfRibbons)
            {
                int AwdId = Int32.Parse(Awd.Key);
                Rows = Database.Query("SELECT * FROM awards WHERE id=@P0 AND awd=@P1 LIMIT 1", Pid, AwdId);
                if (Rows.Count > 0)
                {
                    Model.PlayerSFRibbons.Add(Awd.Key, new Award
                    {
                        Id     = AwdId,
                        Level  = Int32.Parse(Rows[0]["level"].ToString()),
                        Earned = Int32.Parse(Rows[0]["earned"].ToString()),
                        First  = Int32.Parse(Rows[0]["first"].ToString()),
                    });
                }
                else
                {
                    Model.PlayerSFRibbons.Add(Awd.Key, new Award {
                        Id = AwdId
                    });
                }
            }

            #endregion Ribbons

            #region Time To Advancement

            // Fetch all of our awards, so we can determine our qualified rank ups
            Rows = Database.Query("SELECT awd, level FROM awards WHERE id=@P0 ORDER BY level", Pid);
            Dictionary <string, int> Awds = new Dictionary <string, int>();
            foreach (Dictionary <string, object> Row in Rows)
            {
                if (!Awds.ContainsKey(Row["awd"].ToString()))
                {
                    Awds.Add(Row["awd"].ToString(), Int32.Parse(Row["level"].ToString()));
                }
            }

            // Debugging ranks? (personal uses)
            int RanksToShow = 3;
            if (Client.Request.QueryString.ContainsKey("nextranks"))
            {
                Int32.TryParse(Client.Request.QueryString["nextranks"], out RanksToShow);
            }

            // 3 min.
            if (RanksToShow < 3)
            {
                RanksToShow = 3;
            }

            // Get our next ranks
            int Score = Int32.Parse(Model.Player["score"].ToString());
            Model.NextPlayerRanks = RankCalculator.GetNextRanks(
                Score,
                Int32.Parse(Model.Player["rank"].ToString()),
                Awds,
                RanksToShow
                );

            foreach (Rank Rnk in Model.NextPlayerRanks)
            {
                // Get Needed Points for this next rank
                int NP = Rnk.MinPoints - Score;
                Rnk.PointsNeeded = (NP > 0) ? NP : 0;

                // Get our percentage to this next rank based on needed points
                double Perc = Math.Round(((double)Score / Rnk.MinPoints) * 100, 0);
                Rnk.PercentComplete = (Perc > 100) ? 100 : Perc;

                // Get the time to completion, based on our score per minute
                double t = NP / (Model.ScorePerMin / 60);
                if (t < 0)
                {
                    t = 0;
                }
                Rnk.TimeToComplete = (int)t;

                // Get our days to completion time, based on our Join date, Last battle, and average Points per day
                TimeSpan Span = TimeSpan.FromSeconds(
                    Int32.Parse(Model.Player["lastonline"].ToString()) - Int32.Parse(Model.Player["joined"].ToString())
                    );
                double SPD = Math.Round(Score / Span.TotalDays, 0);
                Rnk.DaysToComplete = (int)Math.Round(NP / SPD, 0);
            }

            #endregion Time To Advancement

            // Get player image
            string PlayerImage = Path.Combine(
                Program.RootPath, "Web", "Bf2Stats", "Resources", "images", "soldiers",
                Model.Favorites["army"] + "_" + Model.Favorites["kit"] + "_" + Model.Favorites["weapon"] + ".jpg"
                );

            // Convert fav into a URL
            Model.PlayerImage = (File.Exists(PlayerImage))
                ? Model.Root + "/images/soldiers/" + Model.Favorites["army"] + "_" + Model.Favorites["kit"] + "_" + Model.Favorites["weapon"] + ".jpg"
                : Model.Root + "/images/soldiers/" + Model.Favorites["army"] + "_" + Model.Favorites["kit"] + "_5.jpg";

            // Send the response
            base.SendTemplateResponse("player", typeof(PlayerModel), Model, Pid.ToString());
        }