コード例 #1
0
        public string GeneratePlayerPage(PlayerInfo pi)
        {
            //Program.Log("Generating player page for " + pi.name + " (" + pi.id + ")"); //Enable this for a lot of spam
            stringBuilder = new StringBuilder();

            //Sort entries chronologically (oldest scores first)
            pi.entries.Sort((x, y) => (x.timestamp.CompareTo(y.timestamp)));

            //Get info
            ExtendedPlayerEntry latestEntry = pi.entries[pi.entries.Count - 1];
            long             totalFrames    = 0;
            int              normalClears   = 0;
            int              hardClears     = 0;
            int              specialClears  = 0;
            int              scVisits       = 0;
            int              coVisits       = 0;
            bool             doubleSpecial  = false;
            List <Character> playedChars    = new List <Character>();

            for (int i = 0; i < pi.entries.Count; i++)
            {
                ExtendedPlayerEntry e = pi.entries[i];
                totalFrames += e.runframes;
                switch (e.runend)
                {
                case RunEndCause.NormalClear: normalClears++; break;

                case RunEndCause.HardClear: hardClears++; break;

                case RunEndCause.SpecialClear: specialClears++; break;
                }
                if (e.level >= 19)
                {
                    scVisits++;
                }
                if (e.level >= 23)
                {
                    coVisits++;
                }

                //Accomplishment tracking
                if (i > 0 && e.runend == RunEndCause.SpecialClear)
                {
                    if (pi.entries[i - 1].runend == RunEndCause.SpecialClear)
                    {
                        doubleSpecial = true;
                    }
                }

                bool hasPlayedCharacter = false;
                for (int j = 0; j < playedChars.Count; j++)
                {
                    if (playedChars[j] == pi.entries[i].character)
                    {
                        hasPlayedCharacter = true;
                    }
                }
                if (!hasPlayedCharacter)
                {
                    playedChars.Add(pi.entries[i].character);
                }
            }

            //Check for accomplishments
            List <Accomplishment> accomplishments = new List <Accomplishment>();

            if (specialClears >= 10)
            {
                accomplishments.Add(new Accomplishment("Legend", "This player has reached 7-99 ten times!", "legend.png"));
            }
            if (pi.bestLevelRank == 1)
            {
                accomplishments.Add(new Accomplishment("#1 Depth", "This player has achieved rank #1 in Depth on a daily!", "1depth.png"));
            }
            if (pi.bestScoreRank == 1)
            {
                accomplishments.Add(new Accomplishment("#1 Score", "This player has achieved rank #1 in Score on a daily!", "1score.png"));
            }
            if (pi.bestHardTimeRank == 1)
            {
                accomplishments.Add(new Accomplishment("#1 Hard", "This player got first place in a Hard speedrun on a daily!", "1hard.png"));
            }
            if (pi.bestNormalTimeRank == 1)
            {
                accomplishments.Add(new Accomplishment("#1 Normal", "This player got first place in a Normal speedrun on a daily!", "1normal.png"));
            }
            if (pi.bestSpecialTimeRank == 1)
            {
                accomplishments.Add(new Accomplishment("#1 Special", "This player was the fastest to get a Special clear on a daily!", "1special.png"));
            }
            if (doubleSpecial)
            {
                accomplishments.Add(new Accomplishment("Consistent", "This player has reached 7-99 twice in a row!", "consistent.png"));
            }
            if (pi.bestSpecialTime != -1 && pi.bestSpecialTime < 116 * 60 * 60)
            {
                accomplishments.Add(new Accomplishment("Celeritas", "This player reached 7-99 within 1 hour and 56 minutes!", "celeritas.png"));
            }
            if (specialClears > 0)
            {
                accomplishments.Add(new Accomplishment("One with the Cosmos", "This player has reached 7-99!", "799.png"));
            }
            if (pi.bestScore > 2000000)
            {
                accomplishments.Add(new Accomplishment("Treasure Hunter", "This player has achieved a top score of over $2,000,000!", "2million.png"));
            }
            if (pi.bestHardTime != -1 && pi.bestHardTime < 20 * 60 * 60)
            {
                accomplishments.Add(new Accomplishment("brb killing primordial chaos", "This player has completed a Hard run in under 20 minutes!", "fasthard.png"));
            }
            if ((pi.bestNormalTime != -1 && pi.bestNormalTime < 8 * 60 * 60) || (pi.bestHardTime != -1 && pi.bestHardTime < 8 * 60 * 60))
            {
                accomplishments.Add(new Accomplishment("Really Fast", "This player has completed a run in under 8 minutes!", "fastnormal.png"));
            }
            if (pi.topScoresAverage > 1000000)
            {
                accomplishments.Add(new Accomplishment("More like 'Palace of Treasure' am I right", "This player has a top 10 average score of over $1,000,000!", "million.png"));
            }
            if (coVisits >= 10)
            {
                accomplishments.Add(new Accomplishment("Astronaut", "This player has reached the Cosmic Ocean ten times!", "astronaut.png"));
            }
            if (pi.entries.Count >= 365)
            {
                accomplishments.Add(new Accomplishment("Yearly Challenge", "This player has participated 365 times!", "year.png"));
            }
            if (playedChars.Count == 20)
            {
                accomplishments.Add(new Accomplishment("I Main Random", "This player has played with every character!", "allchars.png"));
            }

            //Write header
            WriteHeader(PageType.Player, pi.name);

            //Return link
            stringBuilder.AppendLine("<center><a href=\"depth.html\">[Click here to return to leaderboard listings]</a><br /><br />");

            //Name(s)
            stringBuilder.Append("<font size=\"7\">");
            stringBuilder.Append(pi.name);
            stringBuilder.Append("</font>");
            BR();
            //Filter duplicate alternate names
            for (int i = 0; i < pi.previousNames.Count; i++)
            {
                if (pi.previousNames[i] == pi.name)
                {
                    pi.previousNames.RemoveAt(i);
                    i--;
                    continue;
                }
                for (int j = 0; j < pi.previousNames.Count; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    if (pi.previousNames[i] == pi.previousNames[j])
                    {
                        pi.previousNames.RemoveAt(j);
                        j--;
                    }
                }
            }
            //List alternate names
            for (int i = 0; i < pi.previousNames.Count; i++)
            {
                stringBuilder.Append("aka ");
                stringBuilder.Append(pi.previousNames[i]);
                BR();
            }

            //Last used character
            stringBuilder.Append("<table><tr><td class=\"c");
            stringBuilder.Append(Convert.ToString((int)latestEntry.character, 16).PadLeft(2, '0'));
            stringBuilder.Append("\"/></tr></table>");
            BR();

            //Info
            PlayerAddition addition = null;

            if (Program.additions.ContainsKey(pi.id))
            {
                addition = Program.additions[pi.id];
            }
            if (addition != null)
            {
                stringBuilder.Append(addition.html); BR();
            }
            if (latestEntry.platform == Platform.Steam)
            {
                stringBuilder.Append("<a href=\"https://steamcommunity.com/profiles/");
                stringBuilder.Append(pi.id);
                stringBuilder.AppendLine("\">Visit Steam profile</a><br />");
            }
            BR();

            //Accomplishments
            if (accomplishments.Count > 0)
            {
                stringBuilder.AppendLine("<table>");
                for (int i = 0; i < accomplishments.Count; i++)
                {
                    WriteKeyValue("<img src=\"" + accomplishments[i].icon + "\">", "<b>" + accomplishments[i].name + "</b>: " + accomplishments[i].description);
                }
                stringBuilder.AppendLine("</table><br />");
            }

            //From here on, do not show links until hovered
            stringBuilder.AppendLine("<div class=\"hidelink\">");

            //General stats
            stringBuilder.AppendLine("<font size=\"5\">General statistics</font><br />");
            stringBuilder.AppendLine("<table>");
            WriteKeyValue("Runs", pi.entries.Count);
            WriteKeyValue("Total playtime", PlayerEntry.GetTime(totalFrames));
            WriteKeyValue("Normal clears", normalClears);
            WriteKeyValue("Sunken City visits", scVisits);
            WriteKeyValue("Hard clears", hardClears);
            WriteKeyValue("CO visits", coVisits);
            WriteKeyValue("Special clears", specialClears);
            stringBuilder.AppendLine("</table><br /><br />");

            //Top average scores
            stringBuilder.AppendLine("<font size=\"5\">Top averages</font><br />");
            stringBuilder.AppendLine("<table>");
            int   wholePart = (int)Math.Floor(pi.topLevelsAverage);
            float fraction  = pi.topLevelsAverage - wholePart;

            stringBuilder.Append("<tr><td><b>Top 10 average depth</b></td><td>");
            stringBuilder.Append(PlayerEntry.GetLevel(wholePart));
            stringBuilder.Append("<font size=\"1\">.");
            string fractionalString = Convert.ToString(Math.Round(fraction, 3));

            if (fractionalString.Length < 2)
            {
                fractionalString = "000";
            }
            else
            {
                fractionalString = fractionalString.Substring(2).PadRight(3, '0');
            }
            stringBuilder.Append(fractionalString);
            stringBuilder.Append("</font>");
            stringBuilder.AppendLine("</td></tr>");
            WriteKeyValue("Top 10 average score", PlayerEntry.GetScore(pi.topScoresAverage));
            WriteKeyValue("Top 5 average time", PlayerEntry.GetTime(pi.topTimesAverage));
            stringBuilder.AppendLine("</table><br /><br />");

            //Best rankings
            stringBuilder.AppendLine("<font size=\"5\">Best rankings</font><br />");
            stringBuilder.AppendLine("<table>");
            WriteTimestampedValue("Best depth ranking", pi.bestLevelRank, pi.bestLevelRankDates);
            WriteTimestampedValue("Best score ranking", pi.bestScoreRank, pi.bestScoreRankDates);
            if (pi.bestNormalTimeRankDates.Count == 0)
            {
                WriteKeyValue("Best Normal ranking", "<i>N/A</i>");
            }
            else
            {
                WriteTimestampedValue("Best Normal ranking", pi.bestNormalTimeRank, pi.bestNormalTimeRankDates);
            }
            if (pi.bestHardTimeRankDates.Count == 0)
            {
                WriteKeyValue("Best Hard ranking", "<i>N/A</i>");
            }
            else
            {
                WriteTimestampedValue("Best Hard ranking", pi.bestHardTimeRank, pi.bestHardTimeRankDates);
            }
            if (pi.bestSpecialTimeRankDates.Count == 0)
            {
                WriteKeyValue("Best Special ranking", "<i>N/A</i>");
            }
            else
            {
                WriteTimestampedValue("Best Special ranking", pi.bestSpecialTimeRank, pi.bestSpecialTimeRankDates);
            }
            stringBuilder.AppendLine("</table><br /><br />");

            //Top results
            stringBuilder.AppendLine("<font size=\"5\">Top results</font><br />");
            stringBuilder.AppendLine("<table>");
            WriteTimestampedValue("Best depth", PlayerEntry.GetLevel(pi.bestLevel), pi.bestLevelDates);
            WriteTimestampedValue("Best score", PlayerEntry.GetScore(pi.bestScore), pi.bestScoreDate);
            if (pi.bestNormalTime == -1)
            {
                WriteKeyValue("Fastest Normal clear", "<i>N/A</i>");
            }
            else
            {
                WriteTimestampedValue("Fastest Normal clear", PlayerEntry.GetTime(pi.bestNormalTime), pi.bestNormalTimeDate);
            }
            if (pi.bestHardTime == -1)
            {
                WriteKeyValue("Fastest Hard clear", "<i>N/A</i>");
            }
            else
            {
                WriteTimestampedValue("Fastest Hard clear", PlayerEntry.GetTime(pi.bestHardTime), pi.bestHardTimeDate);
            }
            if (pi.bestSpecialTime == -1)
            {
                WriteKeyValue("Fastest Special clear", "<i>N/A</i>");
            }
            else
            {
                WriteTimestampedValue("Fastest Special clear", PlayerEntry.GetTime(pi.bestSpecialTime), pi.bestSpecialTimeDate);
            }
            stringBuilder.AppendLine("</table><br /><br />");

            //All results
            pi.entries.Sort((x, y) => (y.timestamp.CompareTo(x.timestamp))); //Sort in reverse chronological order for display
            stringBuilder.AppendLine("<font size=\"5\">All results</font><br />");
            stringBuilder.AppendLine("<table style=\"min-width: 0.5em;\">");

            for (int i = 0; i < pi.entries.Count; i++)
            {
                ExtendedPlayerEntry epe = pi.entries[i];
                bool clear = (epe.runend == RunEndCause.NormalClear || epe.runend == RunEndCause.HardClear || epe.runend == RunEndCause.SpecialClear);
                stringBuilder.Append("<tr><td>");
                string tsString = Program.IntTimestampToString(epe.timestamp);
                stringBuilder.Append("&nbsp;<a href=\"");
                stringBuilder.Append(tsString);
                stringBuilder.Append("_depth.html\">");
                stringBuilder.Append(tsString);
                stringBuilder.Append("</a>&nbsp;");
                stringBuilder.Append("</td><td /><td class=\"c");
                stringBuilder.Append(Convert.ToString((int)epe.character, 16).PadLeft(2, '0'));
                stringBuilder.Append("\" /><td /><td>#");
                stringBuilder.Append(epe.levelRank);
                stringBuilder.Append("</td><td");
                if (clear)
                {
                    stringBuilder.Append(" class=\"clear\">");
                }
                else if (pi.entries[i].level >= COSMIC_OCEAN)
                {
                    stringBuilder.Append(" class=\"co\">");
                }
                else
                {
                    stringBuilder.Append(">");
                }
                stringBuilder.Append(epe.GetLevel());
                stringBuilder.Append("</td><td /><td>#");
                stringBuilder.Append(epe.scoreRank);
                stringBuilder.Append("</td><td>$");
                stringBuilder.Append(epe.GetScore());
                if (clear)
                {
                    stringBuilder.Append("</td><td /><td>#");
                    switch (epe.runend)
                    {
                    case RunEndCause.NormalClear: stringBuilder.Append(epe.normalTimeRank); break;

                    case RunEndCause.HardClear: stringBuilder.Append(epe.hardTimeRank); break;

                    case RunEndCause.SpecialClear: stringBuilder.Append(epe.specialTimeRank); break;
                    }
                    stringBuilder.Append("</td><td>");
                    stringBuilder.Append(epe.GetTime());
                }
                stringBuilder.AppendLine("</td></tr>");
            }
            stringBuilder.AppendLine("</table><br />");

            //Finish
            stringBuilder.AppendLine("</div>"); //hidelink end
            WriteFooter(PageType.Player, true, Convert.ToString((long)pi.id, 16).PadLeft(16, '0') + ".json");

            //Write to file
            return(stringBuilder.ToString());
        }
コード例 #2
0
        public int topTimesAverage    = 9 * 60 * 60 * 60 + 59 * 60 * 60 + 59 * 60; //9:59:99, also just round it

        public void AddEntry(ExtendedPlayerEntry epe)
        {
            //Add entry
            ExtendedPlayerEntry prevEntry = GetEntry(epe.timestamp);

            if (prevEntry != null)
            {
                entries.Remove(prevEntry);
                indexedEntries.Remove(prevEntry.timestamp);
            }
            entries.Add(epe);
            indexedEntries.Add(epe.timestamp, epe);

            //Set ID in case it hasn't been set yet
            this.id = epe.id;

            //Adjust name in case it's changed
            if (this.name != epe.name)
            {
                if (this.name != "Unknown player")
                {
                    this.previousNames.Add(this.name);
                }
                this.name = epe.name;
            }

            //Adjust best level
            if (epe.level > this.bestLevel)
            {
                this.bestLevel = epe.level;
                this.bestLevelDates.Clear();
                this.bestLevelDates.Add(epe.timestamp);
            }
            else if (epe.level == this.bestLevel)
            {
                bool alreadyHas = false;
                for (int i = 0; i < this.bestLevelDates.Count; i++)
                {
                    if (this.bestLevelDates[i] == epe.timestamp)
                    {
                        alreadyHas = true;
                    }
                }
                if (!alreadyHas)
                {
                    this.bestLevelDates.Add(epe.timestamp);
                }
            }
            //Adjust best score
            if (epe.score > this.bestScore)
            {
                this.bestScore     = epe.score;
                this.bestScoreDate = epe.timestamp;
            }
            //Adjust best times
            switch (epe.runend)
            {
            case RunEndCause.NormalClear:
                if (epe.runframes < this.bestNormalTime || this.bestNormalTime == -1)
                {
                    this.bestNormalTime     = epe.runframes;
                    this.bestNormalTimeDate = epe.timestamp;
                }
                break;

            case RunEndCause.HardClear:
                if (epe.runframes < this.bestHardTime || this.bestHardTime == -1)
                {
                    this.bestHardTime     = epe.runframes;
                    this.bestHardTimeDate = epe.timestamp;
                }
                break;

            case RunEndCause.SpecialClear:
                if (epe.runframes < this.bestSpecialTime || this.bestSpecialTime == -1)
                {
                    this.bestSpecialTime     = epe.runframes;
                    this.bestSpecialTimeDate = epe.timestamp;
                }
                break;
            }

            //Adjust best level rank
            if (epe.levelRank <= this.bestLevelRank || this.bestLevelRank == -1)
            {
                if (epe.levelRank < this.bestLevelRank)
                {
                    this.bestLevelRankDates.Clear();
                }
                this.bestLevelRank = epe.levelRank;
                bool alreadyHas = false;
                for (int i = 0; i < this.bestLevelRankDates.Count; i++)
                {
                    if (this.bestLevelRankDates[i] == epe.timestamp)
                    {
                        alreadyHas = true;
                    }
                }
                if (!alreadyHas)
                {
                    this.bestLevelRankDates.Add(epe.timestamp);
                }
            }
            //Adjust best score rank
            if (epe.scoreRank <= this.bestScoreRank || this.bestScoreRank == -1)
            {
                if (epe.scoreRank < this.bestScoreRank)
                {
                    this.bestScoreRankDates.Clear();
                }
                this.bestScoreRank = epe.scoreRank;
                bool alreadyHas = false;
                for (int i = 0; i < this.bestScoreRankDates.Count; i++)
                {
                    if (this.bestScoreRankDates[i] == epe.timestamp)
                    {
                        alreadyHas = true;
                    }
                }
                if (!alreadyHas)
                {
                    this.bestScoreRankDates.Add(epe.timestamp);
                }
            }
            //Adjust best time ranks
            if (epe.normalTimeRank != -1 && (epe.normalTimeRank <= this.bestNormalTimeRank || this.bestNormalTimeRank == -1))
            {
                if (epe.normalTimeRank < this.bestNormalTimeRank)
                {
                    this.bestNormalTimeRankDates.Clear();
                }
                this.bestNormalTimeRank = epe.normalTimeRank;
                bool alreadyHas = false;
                for (int i = 0; i < this.bestNormalTimeRankDates.Count; i++)
                {
                    if (this.bestNormalTimeRankDates[i] == epe.timestamp)
                    {
                        alreadyHas = true;
                    }
                }
                if (!alreadyHas)
                {
                    this.bestNormalTimeRankDates.Add(epe.timestamp);
                }
            }
            if (epe.hardTimeRank != -1 && (epe.hardTimeRank <= this.bestHardTimeRank || this.bestHardTimeRank == -1))
            {
                if (epe.hardTimeRank < this.bestHardTimeRank)
                {
                    this.bestHardTimeRankDates.Clear();
                }
                this.bestHardTimeRank = epe.hardTimeRank;
                bool alreadyHas = false;
                for (int i = 0; i < this.bestHardTimeRankDates.Count; i++)
                {
                    if (this.bestHardTimeRankDates[i] == epe.timestamp)
                    {
                        alreadyHas = true;
                    }
                }
                if (!alreadyHas)
                {
                    this.bestHardTimeRankDates.Add(epe.timestamp);
                }
            }
            if (epe.specialTimeRank != -1 && (epe.specialTimeRank <= this.bestSpecialTimeRank || this.bestSpecialTimeRank == -1))
            {
                if (epe.specialTimeRank < this.bestSpecialTimeRank)
                {
                    this.bestSpecialTimeRankDates.Clear();
                }
                this.bestSpecialTimeRank = epe.specialTimeRank;
                bool alreadyHas = false;
                for (int i = 0; i < this.bestSpecialTimeRankDates.Count; i++)
                {
                    if (this.bestSpecialTimeRankDates[i] == epe.timestamp)
                    {
                        alreadyHas = true;
                    }
                }
                if (!alreadyHas)
                {
                    this.bestSpecialTimeRankDates.Add(epe.timestamp);
                }
            }

            //Get top entries
            List <ExtendedPlayerEntry> adjustedEntries = null;

            if (entries.Count > 9)
            {
                adjustedEntries = entries;
            }
            else
            {
                adjustedEntries = new List <ExtendedPlayerEntry>(entries);
            }
            int num = 1;

            while (adjustedEntries.Count < 10)
            {
                adjustedEntries.Add(new ExtendedPlayerEntry(new PlayerEntry(), 0, 0, num)); //Avoid duplicate timestamps
                num++;
            }
            //Top 10 depths
            adjustedEntries.Sort((x, y) => (y.level.CompareTo(x.level)));
            topLevels.Clear();
            topLevelsAverage = 0;
            for (int i = 0; i < 10; i++)
            {
                topLevels.Add(adjustedEntries[i].timestamp);
                topLevelsAverage += adjustedEntries[i].level;
            }
            topLevelsAverage /= 10f;
            //Top 10 scores
            adjustedEntries.Sort((x, y) => (y.score.CompareTo(x.score)));
            topScores.Clear();
            topScoresAverage = 0;
            for (int i = 0; i < 10; i++)
            {
                topScores.Add(adjustedEntries[i].timestamp);
                topScoresAverage += adjustedEntries[i].score;
            }
            topScoresAverage = Convert.ToInt32(Math.Round((float)topScoresAverage / 10f));
            //Top 5 times
            List <ExtendedPlayerEntry> normalClears  = new List <ExtendedPlayerEntry>();
            List <ExtendedPlayerEntry> hardClears    = new List <ExtendedPlayerEntry>();
            List <ExtendedPlayerEntry> specialClears = new List <ExtendedPlayerEntry>();
            List <ExtendedPlayerEntry> allClears     = new List <ExtendedPlayerEntry>();

            for (int i = 0; i < adjustedEntries.Count; i++)
            {
                switch (adjustedEntries[i].runend)
                {
                case RunEndCause.NormalClear:
                    normalClears.Add(adjustedEntries[i]);
                    allClears.Add(adjustedEntries[i]);
                    break;

                case RunEndCause.HardClear:
                    hardClears.Add(adjustedEntries[i]);
                    allClears.Add(adjustedEntries[i]);
                    break;

                case RunEndCause.SpecialClear:
                    specialClears.Add(adjustedEntries[i]);
                    allClears.Add(adjustedEntries[i]);
                    break;
                }
            }
            while (allClears.Count < 5)
            {
                allClears.Add(new ExtendedPlayerEntry(new PlayerEntry(), 0, 0, 0));
            }
            allClears.Sort((x, y) => (x.runframes.CompareTo(y.runframes)));
            topTimes.Clear();
            topTimesAverage = 0;
            for (int i = 0; i < 5; i++)
            {
                topTimes.Add(allClears[i].timestamp);
                topTimesAverage += allClears[i].runframes;
            }
            topTimesAverage = Convert.ToInt32(Math.Round((float)topTimesAverage / 5f));
        }