示例#1
0
        public static async Task Percent(CommandContext bc)
        {
            // get rsn
            var rsn = await bc.GetPlayerName(bc.MessageTokens.Length > 1 ? bc.MessageTokens.Join(1) : bc.From.Nickname);

            var p = await Player.FromHiscores(rsn);
            if (!p.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                return;
            }

            long totalExp = p.Skills[Skill.OVER].Exp;
            long combatExp = p.Skills[Skill.COMB].Exp;
            long f2pExp = p.Skills.F2pExp;

            // slayer
            long hits_exp_gained = p.Skills[Skill.HITP].Exp - 1154;
            var expected_max_slayer_exp = (int) (hits_exp_gained * 3.0 / 4.0);

            // pc
            long expected_combat_xp = p.Skills[Skill.HITP].Exp + p.Skills[Skill.HITP].Exp * 12 / 4;
            long current_combat_xp = p.Skills[Skill.HITP].Exp + p.Skills[Skill.ATTA].Exp + p.Skills[Skill.STRE].Exp + p.Skills[Skill.DEFE].Exp + p.Skills[Skill.RANG].Exp;

            await bc.SendReply(@"\b{0}\b statistic percentages | Total exp: \c07{1:N0}\c | Combat exp: \c07{2:N0}\c (\c07{3:0.##}%\c) | F2P exp: \c07{4:N0}\c (\c07{5:0.##}%\c) | Slayer%: \c07{6:0.##}% - {7:0.##}%\c | PestControl%: \c07{8:0.##}%\c", rsn, totalExp, combatExp, (double) combatExp / totalExp * 100, f2pExp, (double) f2pExp / totalExp * 100, (double) p.Skills[Skill.SLAY].Exp / expected_max_slayer_exp * 100, (double) p.Skills[Skill.SLAY].Exp / (expected_max_slayer_exp - (hits_exp_gained / 133)) * 100, (double) (current_combat_xp - expected_combat_xp) / current_combat_xp * 100);
        }
示例#2
0
        public static async Task Start(CommandContext bc)
        {
            // get rsn
            string rsn = await bc.GetPlayerName(bc.From.Nickname);

            var p = await Player.FromHiscores(rsn);
            if (!p.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                return;
            }

            // get timer name
            string name = string.Empty;
            int indexOfSharp = bc.Message.IndexOf('#');
            if (indexOfSharp > 0)
            {
                name = bc.Message.Substring(indexOfSharp + 1);
                bc.Message = bc.Message.Substring(0, indexOfSharp - 1);
            }

            // get skill
            string skill = Skill.OVER;
            if (bc.MessageTokens.Length > 1)
            {
                Skill.TryParse(bc.MessageTokens[1], ref skill);
            }

            // remove previous timer with this name, if any
            await Database.ExecuteNonQuery("DELETE FROM timers_exp WHERE fingerprint='" + bc.From.FingerPrint + "' AND name='" + name.Replace("'", "''") + "'");

            // start a new timer with this name
            await Database.Insert("timers_exp", "fingerprint", bc.From.FingerPrint, "name", name, "skill", skill, "exp", p.Skills[skill].Exp.ToStringI(), "datetime", DateTime.UtcNow.ToStringI("yyyyMMddHHmmss"));
            await bc.SendReply(@"\b{0}\b starting exp of \c07{1:e}\c in \u{1:n}\u has been recorded{2}.", rsn, p.Skills[skill], name.Length > 0 ? @" on timer \c07" + name + @"\c" : string.Empty);
        }
示例#3
0
        public static async Task Graph(CommandContext bc)
        {
            string skill = Skill.OVER;
            string rsn = await bc.GetPlayerName(bc.From.Nickname);

            if (bc.MessageTokens.Length > 1)
            {
                if (Skill.TryParse(bc.MessageTokens[1], ref skill))
                {
                    if (bc.MessageTokens.Length > 2)
                    {
                        rsn = await bc.GetPlayerName(bc.MessageTokens.Join(2));
                    }
                }
                else
                {
                    rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
                }
            }

            await bc.SendReply(@"\b{0}\b \c07{1}\c graph | level: \c12http://t.rscript.org/graph-{0}.{2}.lvl.png\c | exp: \c12http://t.rscript.org/graph-{0}.{2}.png\c | rank: \c12http://t.rscript.org/graph-{0}.{2}.rank.png\c", rsn, skill.ToLowerInvariant(), Skill.NameToId(skill));
        }
示例#4
0
        public static async Task F2pPercent(CommandContext bc)
        {
            // get rsn
            string rsn;
            if (bc.MessageTokens.Length > 1)
            {
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
            }
            else
            {
                rsn = await bc.GetPlayerName(bc.From.Nickname);
            }

            var p = await Player.FromHiscores(rsn);
            if (!p.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                return;
            }

            await bc.SendReply(@"\b{0}\b is \c07{1:0.##}%\c f2p based, with \c07{2:N0}\c f2p based exp. and \c07{3:e}\c total exp.", rsn, (double) p.Skills.F2pExp / (double) p.Skills[Skill.OVER].Exp * 100, p.Skills.F2pExp, p.Skills[Skill.OVER]);
        }
示例#5
0
        public static async Task Check(CommandContext bc)
        {
            // get rsn
            string rsn = await bc.GetPlayerName(bc.From.Nickname);

            var p = await Player.FromHiscores(rsn);
            if (!p.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                return;
            }

            // get timer name
            string name = string.Empty;
            int indexofsharp = bc.Message.IndexOf('#');
            if (indexofsharp > 0)
            {
                name = bc.Message.Substring(indexofsharp + 1);
                bc.Message = bc.Message.Substring(0, indexofsharp - 1);
            }

            var rs = await Database.FetchFirst("SELECT skill,exp,datetime FROM timers_exp WHERE fingerprint=@fingerprint AND name=@name LIMIT 1", new MySqlParameter("@fingerprint", bc.From.FingerPrint), new MySqlParameter("@name", name));
            if (rs != null)
            {
                string skill = rs.GetString(0);

                long gained_exp = p.Skills[skill].Exp - (uint) rs["exp"];
                TimeSpan time = DateTime.UtcNow - rs.GetString(2).ToDateTime();

                var reply = @"You gained \c07{0:N0}\c \u{1}\u exp in \c07{2}\c. That's \c07{3:N0}\c exp/h.".FormatWith(gained_exp, skill.ToLowerInvariant(), time.ToLongString(), (double) gained_exp / time.TotalHours);
                if (gained_exp > 0 && skill != Skill.OVER && skill != Skill.COMB && p.Skills[skill].VLevel < 126)
                {
                    reply += @" Estimated time to level up: \c07{0}\c".FormatWith(TimeSpan.FromSeconds(p.Skills[skill].ExpToVLevel * time.TotalSeconds / gained_exp).ToLongString());
                }
                await bc.SendReply(reply);
            }
            else
            {
                if (name.Length > 0)
                {
                    await bc.SendReply("You must start timing a skill on that timer first.");
                }
                else
                {
                    await bc.SendReply("You must start timing a skill first.");
                }
            }
        }
示例#6
0
        public static async Task Alog(CommandContext bc)
        {
            int timeSpan = 0;
            string timeSpanName = string.Empty;
            Match timeInterval = Regex.Match(bc.Message, @"@(.+?)( |$)");
            if (timeInterval.Success)
            {
                var timePeriod = new TimeInterval();
                if (timePeriod.Parse(timeInterval.Groups[1].Value))
                {
                    timeSpan = (int) timePeriod.Time.TotalSeconds;
                    timeSpanName = timePeriod.Name;
                }
                else if (timeInterval.Groups[1].Value == "all")
                {
                    timeSpan = int.MaxValue;
                }
                bc.Message = Regex.Replace(bc.Message, @"@(.+?)( |$)", string.Empty, RegexOptions.IgnoreCase);
                bc.Message = bc.Message.Trim();
            }

            var rsn = await bc.GetPlayerName(bc.From.Nickname);
            if (bc.MessageTokens.GetLength(0) > 1)
            {
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
            }

            List<RssItem> list = null;
            try
            {
                var reader = new RssManager("http://services.runescape.com/m=adventurers-log/rssfeed?searchName=" + rsn);
                reader.GetFeed();
                list = reader.RssItems;
            }
            catch
            {
            }

            if (list == null)
            {
                await bc.SendReply(@"No achievements found for \c7{0}\c{1}. The profile may be private, the player may be f2p, or the rsn incorrect.", rsn, string.IsNullOrEmpty(timeSpanName) ? string.Empty : @" in " + timeSpanName);
                return;
            }

            var p = await Player.FromHiscores(rsn);
            list.Sort((i1, i2) => i2.Date.CompareTo(i1.Date));
            if (timeSpan > 0)
            {
                list.RemoveAll(i => (DateTime.UtcNow - i.Date).TotalSeconds > timeSpan);
            }
            else if (list.Count > 15)
            {
                list.RemoveAll(i => i.Date < list[14].Date);
                timeSpanName = "recent";
            }
            if (list.Count == 0 || !p.Ranked)
            {
                await bc.SendReply(@"No achievements found for \c7{0}\c{1}. The profile may be private, the player may be f2p, or the rsn incorrect.", rsn, string.IsNullOrEmpty(timeSpanName) ? string.Empty : @" in " + timeSpanName);
                return;
            }

            const string questRegex = @"Quest complete: (.+)";
            const string killRegex = @"killed the player (.+?)\.|I killed\s*(?:an?|the)?\s*(.+?)\.?$";
            const string levelRegex = @"Level?led up (\w+)\.?|Levelled all skills over (\d+)";
            const string itemRegex = @"Item found: (?:an?|some) (.+)";
            const string expRegex = @"(\d+)XP in (\w+)";
            const string duRegex = @"Dungeon level (\d+) reached.";

            var alogItems = new Dictionary<string, Dictionary<string, AlogItem>> {
                { "I reached", new Dictionary<string, AlogItem>() },
                { "I gained", new Dictionary<string, AlogItem>() },
                { "I killed", new Dictionary<string, AlogItem>() },
                { "I found", new Dictionary<string, AlogItem>() },
                { "I completed", new Dictionary<string, AlogItem>() },
                { "Others", new Dictionary<string, AlogItem>() }
            };
            foreach (RssItem item in list)
            {
                Match M = Regex.Match(item.Title, questRegex);
                if (M.Success)
                {
                    var quest = new AlogItem(item, M, "I completed");
                    alogItems["I completed"].Add(alogItems["I completed"].Count.ToStringI(), quest);
                    continue;
                }
                M = Regex.Match(item.Title, killRegex);
                if (M.Success)
                {
                    var kill = new AlogItem(item, M, "I killed");
                    string npc = Regex.Replace(kill.Info[0].Replace("monsters", "monster"), @"\W", " ");
                    if (alogItems["I killed"].ContainsKey(npc))
                    {
                        alogItems["I killed"][npc].Amount += kill.Amount;
                    }
                    else
                    {
                        kill.Info[0] = npc;
                        alogItems["I killed"].Add(npc, kill);
                    }
                    continue;
                }
                M = Regex.Match(item.Title, levelRegex);
                if (M.Success)
                {
                    var level = new AlogItem(item, M, "I gained");
                    try
                    {
                        level.Info[0] = Skill.Parse(level.Info[0]);
                        if (alogItems["I gained"].ContainsKey(level.Info[0]))
                        {
                            alogItems["I gained"][level.Info[0]].Amount++;
                        }
                        else
                        {
                            alogItems["I gained"].Add(level.Info[0], level);
                            alogItems["I gained"][level.Info[0]].Info[1] = p.Skills[level.Info[0]].Level.ToStringI();
                        }
                    }
                    catch
                    {
                        if (alogItems["I gained"].ContainsKey("all"))
                        {
                            if (level.Info[1].ToInt32() > alogItems["I gained"]["all"].Info[1].ToInt32())
                            {
                                alogItems["I gained"]["all"].Info[0] = "all";
                                alogItems["I gained"]["all"].Info[1] = level.Info[1];
                            }
                        }
                        else
                        {
                            alogItems["I gained"].Add("all", level);
                            alogItems["I gained"]["all"].Info[0] = "all";
                        }
                    }
                    continue;
                }
                M = Regex.Match(item.Title, itemRegex);
                if (M.Success)
                {
                    var drop = new AlogItem(item, M, "I found");
                    if (alogItems["I found"].ContainsKey(drop.Info[0]))
                    {
                        alogItems["I found"][drop.Info[0]].Amount++;
                    }
                    else
                    {
                        alogItems["I found"].Add(drop.Info[0], drop);
                    }
                    continue;
                }
                M = Regex.Match(item.Title, duRegex);
                if (M.Success)
                {
                    var duFloor = new AlogItem(item, M, "Others");
                    if (!alogItems["Others"].ContainsKey("duFloor"))
                    {
                        alogItems["Others"].Add("duFloor", duFloor);
                        alogItems["Others"]["duFloor"].Info[1] = "1";
                    }
                    alogItems["Others"]["duFloor"].Info[0] = "duFloor";
                    if (M.Groups[1].Value.ToInt32() > alogItems["Others"]["duFloor"].Info[1].ToInt32())
                    {
                        alogItems["Others"]["duFloor"].Info[1] = M.Groups[1].Value;
                    }
                    continue;
                }
                M = Regex.Match(item.Title, expRegex);
                if (M.Success)
                {
                    var exp = new AlogItem(item, M, "I reached");
                    if (alogItems["I reached"].ContainsKey(exp.Info[1]))
                    {
                        if (alogItems["I reached"][exp.Info[1]].Info[0].ToInt32() < exp.Info[0].ToInt32())
                        {
                            alogItems["I reached"].Remove(exp.Info[1]);
                            alogItems["I reached"].Add(exp.Info[1], exp);
                        }
                    }
                    else
                    {
                        alogItems["I reached"].Add(exp.Info[1], exp);
                    }
                    continue;
                }
                var other = new AlogItem(item, null, "Others");
                alogItems["Others"].Add(alogItems["Others"].Count.ToStringI(), other);
            }
            string reply = rsn + "'s achievements" + (string.IsNullOrEmpty(timeSpanName) ? string.Empty : " (" + timeSpanName + ")") + ": ";
            foreach (var category in alogItems)
            {
                if (category.Value.Count == 0)
                {
                    continue;
                }
                reply += category.Key + ": ";
                foreach (AlogItem item in category.Value.Values)
                {
                    string amount = string.Empty;
                    if (item.Amount > 1)
                    {
                        amount = @"\c07{0}\cx ".FormatWith(item.Amount);
                    }
                    if (category.Key == "I reached")
                    {
                        var skill = new Skill(item.Info[1], 1, 1);
                        reply += @"\c07{0}\c {1} exp; ".FormatWith(item.Info[0].ToInt32().ToShortString(1), skill.ShortName);
                    }
                    else if (category.Key == "I gained")
                    {
                        if (item.Info[0] == "all")
                        {
                            reply += @"All skills now at least \c07{0}\c; ".FormatWith(item.Info[1]);
                        }
                        else
                        {
                            var skill = new Skill(item.Info[0], 1, 1);
                            reply += @"\c07{0}\c {1} levels(->{2}); ".FormatWith(item.Amount, skill.ShortName, item.Info[1]);
                        }
                    }
                    else if (item.Info[0] == "duFloor")
                    {
                        reply += @"Unlocked dungeon floor \c07{0}\c; ".FormatWith(item.Info[1]);
                    }
                    else
                    {
                        reply += amount + @"\c07{0}\c; ".FormatWith(item.Info[0]);
                    }
                }
            }
            await bc.SendReply(reply.Trim());
        }
示例#7
0
        public static async Task Track(CommandContext bc)
        {
            // get time
            int intervalTime = 604800;
            string intervalName = "1 week";
            Match interval = Regex.Match(bc.Message, @"@(\d+)?(second|minute|month|hour|week|year|sec|min|day|s|m|h|d|w|y)s?", RegexOptions.IgnoreCase);
            if (interval.Success)
            {
                if (interval.Groups[1].Value.Length > 0)
                {
                    intervalTime = int.Parse(interval.Groups[1].Value, CultureInfo.InvariantCulture);
                }
                else
                {
                    intervalTime = 1;
                }
                if (intervalTime < 1)
                {
                    intervalTime = 1;
                }
                switch (interval.Groups[2].Value)
                {
                    case "second":
                    case "sec":
                    case "s":
                        intervalName = intervalTime + " second" + (intervalTime == 1 ? string.Empty : "s");
                        break;
                    case "minute":
                    case "min":
                    case "m":
                        intervalName = intervalTime + " minute" + (intervalTime == 1 ? string.Empty : "s");
                        intervalTime *= 60;
                        break;
                    case "hour":
                    case "h":
                        intervalName = intervalTime + " hour" + (intervalTime == 1 ? string.Empty : "s");
                        intervalTime *= 3600;
                        break;
                    case "day":
                    case "d":
                        intervalName = intervalTime + " day" + (intervalTime == 1 ? string.Empty : "s");
                        intervalTime *= 86400;
                        break;
                    case "week":
                    case "w":
                        intervalName = intervalTime + " week" + (intervalTime == 1 ? string.Empty : "s");
                        intervalTime *= 604800;
                        break;
                    case "month":
                        intervalName = intervalTime + " month" + (intervalTime == 1 ? string.Empty : "s");
                        intervalTime *= 2629746;
                        break;
                    case "year":
                    case "y":
                        intervalName = intervalTime + " year" + (intervalTime == 1 ? string.Empty : "s");
                        intervalTime *= 31556952;
                        break;
                }
                bc.Message = Regex.Replace(bc.Message, @"@(\d+)?(second|minute|month|hour|week|year|sec|min|day|s|m|h|d|w|y)s?", string.Empty, RegexOptions.IgnoreCase);
                bc.Message = bc.Message.Trim();
            }
            intervalName = "last " + intervalName;

            // get rsn
            string rsn;
            if (bc.MessageTokens.Length > 1)
            {
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
            }
            else
            {
                rsn = await bc.GetPlayerName(bc.From.Nickname);
            }

            // Get new player
            var PlayerNew = await Player.FromHiscores(rsn);
            if (!PlayerNew.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                return;
            }

            // Get old player
            var PlayerOld = new Player(rsn, intervalTime);
            if (!PlayerOld.Ranked)
            {
                await bc.SendReply(@"\b{0}\b wasn't being tracked on {1}.", rsn, DateTime.UtcNow.AddSeconds(-intervalTime).ToStringI("yyyy-MMM-dd"));
                return;
            }

            // 1st line: overall / combat
            string ReplyMsg = @"\b{0}\b \u{1}\u skills:".FormatWith(rsn, intervalName);
            Skill OverallDif = PlayerNew.Skills[Skill.OVER] - PlayerOld.Skills[Skill.OVER];
            if (OverallDif.Exp <= 0)
            {
                await bc.SendReply(@"No performance for \b{0}\b within this period.", rsn);
            }
            else
            {
                Skill CombatDif = PlayerNew.Skills[Skill.COMB] - PlayerOld.Skills[Skill.COMB];

                string DifLevel = string.Empty;
                if (OverallDif.Level > 0)
                {
                    DifLevel = @" [\b+{0}\b]".FormatWith(OverallDif.Level);
                }
                ReplyMsg += @" \c07Overall\c lvl {0} \c3+{1}\c xp (Avg. hourly exp.: \c07{2}\c)".FormatWith(PlayerNew.Skills[Skill.OVER].Level + DifLevel, OverallDif.Exp.ToShortString(1), (OverallDif.Exp / (intervalTime / 3600.0)).ToShortString(0));
                DifLevel = string.Empty;
                if (CombatDif.Level > 0)
                {
                    DifLevel = @" [\b+{0}\b]".FormatWith(CombatDif.Level);
                }
                ReplyMsg += @"; \c7Combat\c lvl {0} \c03+{1}\c xp (\c07{2}%\c)".FormatWith(PlayerNew.Skills[Skill.COMB].Level + DifLevel, CombatDif.Exp.ToShortString(1), (CombatDif.Exp / (double) OverallDif.Exp * 100.0).ToShortString(1));
                await bc.SendReply(ReplyMsg);

                // 2nd line: skills list
                List<Skill> SkillsDif = (from SkillNow in PlayerNew.Skills.Values
                                         where SkillNow.Name != Skill.OVER && SkillNow.Name != Skill.COMB
                                         select SkillNow - PlayerOld.Skills[SkillNow.Name]).ToList();
                SkillsDif.Sort();

                ReplyMsg = @"\b{0}\b \u{1}\u skills:".FormatWith(rsn, intervalName);
                for (int i = 0; i < 10; i++)
                {
                    if (SkillsDif[i].Exp > 0)
                    {
                        DifLevel = string.Empty;
                        if (SkillsDif[i].Level > 0)
                        {
                            DifLevel = @" [\b+{0}\b]".FormatWith(SkillsDif[i].Level);
                        }
                        ReplyMsg += @" \c07{0}\c lvl {1} \c3+{2}\c xp;".FormatWith(SkillsDif[i].Name, PlayerNew.Skills[SkillsDif[i].Name].Level + DifLevel, SkillsDif[i].Exp.ToShortString(1));
                    }
                }
                await bc.SendReply(ReplyMsg);
            }
        }
示例#8
0
        public static async Task ClanPerformance(CommandContext bc)
        {
            string clanInitials;
            string clanName;
            if (bc.Message.ContainsI("SS"))
            {
                clanInitials = "SS";
                clanName = "Supreme Skillers";
            }
            else if (bc.Message.ContainsI("TS"))
            {
                clanInitials = "TS";
                clanName = "True Skillers";
            }
            else
            {
                clanInitials = "PT";
                clanName = "Portugal";
            }

            var rsn = await bc.GetPlayerName(bc.From.Nickname);
            string skill = null;
            int rank = 0;
            bool IsIndividual = false;

            // get last updated player date
            DateTime lastUpdate = (await Database.Lookup<string>("lastUpdate", "players", "ORDER BY lastUpdate DESC")).ToDateTime();

            DateTime firstDay,
                     lastDay;
            if (bc.MessageTokens[0].Contains("yesterday") || bc.MessageTokens[0].Contains("yday"))
            {
                lastDay = lastUpdate;
                firstDay = lastDay.AddDays(-1);
            }
            else if (bc.MessageTokens[0].Contains("lastweek") | bc.MessageTokens[0].Contains("lweek"))
            {
                lastDay = lastUpdate.AddDays(-((int) lastUpdate.DayOfWeek));
                firstDay = lastDay.AddDays(-7);
            }
            else if (bc.MessageTokens[0].Contains("lastmonth") | bc.MessageTokens[0].Contains("lmonth"))
            {
                lastDay = lastUpdate.AddDays(1 - lastUpdate.Day);
                firstDay = lastDay.AddMonths(-1);
            }
            else if (bc.MessageTokens[0].Contains("lastyear") | bc.MessageTokens[0].Contains("lyear"))
            {
                lastDay = lastUpdate.AddDays(1 - lastUpdate.DayOfYear);
                firstDay = lastDay.AddYears(-1);
            }
            else if (bc.MessageTokens[0].Contains("week"))
            {
                firstDay = lastUpdate.AddDays(-((int) lastUpdate.DayOfWeek));
                lastDay = lastUpdate;
            }
            else if (bc.MessageTokens[0].Contains("month"))
            {
                firstDay = lastUpdate.AddDays(1 - lastUpdate.Day);
                lastDay = lastUpdate;
            }
            else if (bc.MessageTokens[0].Contains("year"))
            {
                firstDay = lastUpdate.AddDays(1 - lastUpdate.DayOfYear);
                lastDay = lastUpdate;
            }
            else
            {
                Match M = Regex.Match(bc.MessageTokens[0], "last(\\d+)days");
                if (M.Success)
                {
                    lastDay = lastUpdate;
                    firstDay = lastDay.AddDays(-int.Parse(M.Groups[1].Value, CultureInfo.InvariantCulture));
                }
                else
                {
                    return;
                }
            }
            if (firstDay == lastDay)
            {
                return;
            }

            // Create a list of Clan players
            var clanPlayers = await Players.FromClanAsPeriod(clanInitials, firstDay, lastDay);

            // Parse command arguments
            if (bc.MessageTokens.Length == 1)
            {
                // !ClanTop
                IsIndividual = true;
            }
            else if (Skill.TryParse(bc.MessageTokens[1], ref skill))
            {
                // !ClanTop Skill
                rank = 1;

                // Clean and sort clan members by specified skill
                clanPlayers = clanPlayers.Where(p => p.Skills[skill].Exp > 0)
                                         .OrderByDescending(p => p.Skills[skill].Exp)
                                         .ToList();

                if (bc.MessageTokens.Length > 2)
                {
                    if (int.TryParse(bc.MessageTokens[2], out rank))
                    {
                        // !ClanTop Skill Rank
                    }
                    else if (bc.MessageTokens.Length == 3 && bc.MessageTokens[2].ToUpperInvariant() == "@LAST")
                    {
                        // !ClanTop Skill @last
                        rank = clanPlayers.Count;
                    }
                    else
                    {
                        // !ClanTop Skill
                        rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
                        var indexOfPlayer = clanPlayers.FindIndex(p => p.Name.EqualsI(rsn));
                        if (indexOfPlayer != -1)
                        {
                            rank = indexOfPlayer + 1;
                        }
                    }
                }
            }
            else
            {
                // !ClanTop RSN
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
                IsIndividual = true;
            }

            if (IsIndividual)
            {
                var player = clanPlayers.FirstOrDefault(p => p.Name.EqualsI(rsn));
                if (player != null)
                {
                    // individual skill ranks
                    var reply = @"[{0}] \b{1}\b skill ranks:";
                    foreach (var s in player.Skills.Values.Where(s => s.Exp > 0))
                    {
                        var indexOfPlayer = clanPlayers.OrderBy(p => p.Skills[s.Name]).IndexOf(player);
                        reply += @" \c07#{0}\c {1};".FormatWith(indexOfPlayer + 1, s.ShortName);
                    }
                    await bc.SendReply(reply, clanInitials, rsn);
                }
                else
                {
                    await bc.SendReply(@"\b{0}\b wasn't at {1}.", rsn, clanName);
                }
                return;
            }
            
            // Get input player rank
            var inputPlayerName = await bc.GetPlayerName(bc.From.Nickname);
            var inputPlayerRank = clanPlayers.FindIndex(p => p.Name.EqualsI(inputPlayerName)) + 1;

            // fix rank
            if (rank < 1)
            {
                rank = 1;
            }
            else if (rank > clanPlayers.Count)
            {
                rank = clanPlayers.Count;
            }

            int MinRank = rank - 6;
            if (MinRank < 0)
            {
                MinRank = 0;
            }
            else if (MinRank > clanPlayers.Count - 11)
            {
                MinRank = clanPlayers.Count - 11;
            }

            if (clanPlayers.Count > 0)
            {
                string reply = @"[{0}] \u{1}\u ranking:".FormatWith(clanInitials, skill.ToLowerInvariant());
                if (inputPlayerRank > 0 && inputPlayerRank <= MinRank)
                {
                    reply += @" \c7#{0}\c \u{1}\u ({2:e});".FormatWith(inputPlayerRank, clanPlayers[inputPlayerRank - 1].Name, clanPlayers[inputPlayerRank - 1].Skills[skill]);
                }

                for (int i = MinRank; i < Math.Min(MinRank + 11, clanPlayers.Count); i++)
                {
                    reply += " ";
                    if (i == rank - 1)
                    {
                        reply += @"\b";
                    }
                    reply += @"\c07#{0}\c ".FormatWith(i + 1);
                    if (i == inputPlayerRank - 1)
                    {
                        reply += @"\u";
                    }
                    reply += clanPlayers[i].Name;
                    if (i == inputPlayerRank - 1)
                    {
                        reply += @"\u";
                    }
                    reply += " (" + clanPlayers[i].Skills[skill].ToStringI("e") + ")";
                    if (i == rank - 1)
                    {
                        reply += @"\b";
                    }
                    reply += ";";
                }

                if (inputPlayerRank > 0 && inputPlayerRank > MinRank + 11)
                {
                    reply += @" \c7#{0}\c \u{1}\u ({2:e});".FormatWith(inputPlayerRank, clanPlayers[inputPlayerRank - 1].Name, clanPlayers[inputPlayerRank - 1].Skills[skill]);
                }

                await bc.SendReply(reply);
            }
            else
            {
                await bc.SendReply(clanName + " didn't have any member ranked at this skill.");
            }
        }
示例#9
0
        public static async Task Activity(CommandContext bc)
        {
            // get player
            var player = await Player.FromHiscores(await bc.GetPlayerName(bc.MessageTokens.Length > 1 ? bc.MessageTokens.Join(1) : bc.From.Nickname));
            if (player.Ranked)
            {
                Activity activity = player.Activities[Bot.Activity.Parse(bc.MessageTokens[0])];
                if (activity.Rank > 0)
                {
                    string reply = @"\b{0}\b \c07{1:n}\c | score: \c07{1:s}\c | rank: \c07{1:R}\c".FormatWith(player.Name, activity);

                    // Add SS rank if applicable
                    var ssPlayers = (await Players.FromClan("SS")).OrderBy(p => p.Activities[activity.Name]);
                    var ssRank = ssPlayers.FindIndex(p => p.Name.EqualsI(player.Name));
                    if (ssRank != -1)
                    {
                        reply += @" (SS rank: \c07{0}\c)".FormatWith(ssRank + 1);
                    }

                    await bc.SendReply(reply);

                    // Show player performance if applicable
                    var dblastupdate = await Database.LastUpdate(player.Name);
                    if (dblastupdate != null && dblastupdate.Length == 8)
                    {
                        DateTime lastupdate = dblastupdate.ToDateTime();
                        string perf;
                        reply = string.Empty;

                        var p_old = await Player.FromDatabase(player.Name, lastupdate);
                        if (p_old.Ranked)
                        {
                            perf = _GetPerformance("Today", p_old.Activities[activity.Name], activity);
                            if (perf != null)
                            {
                                reply += perf + " | ";
                            }
                        }
                        p_old = await Player.FromDatabase(player.Name, lastupdate.AddDays(-((int) lastupdate.DayOfWeek)));
                        if (p_old.Ranked)
                        {
                            perf = _GetPerformance("Week", p_old.Activities[activity.Name], activity);
                            if (perf != null)
                            {
                                reply += perf + " | ";
                            }
                        }
                        p_old = await Player.FromDatabase(player.Name, lastupdate.AddDays(1 - lastupdate.Day));
                        if (p_old.Ranked)
                        {
                            perf = _GetPerformance("Month", p_old.Activities[activity.Name], activity);
                            if (perf != null)
                            {
                                reply += perf + " | ";
                            }
                        }
                        p_old = await Player.FromDatabase(player.Name, lastupdate.AddDays(1 - lastupdate.DayOfYear));
                        if (p_old.Ranked)
                        {
                            perf = _GetPerformance("Year", p_old.Activities[activity.Name], activity);
                            if (perf != null)
                            {
                                reply += perf;
                            }
                        }
                        if (reply.Length > 0)
                        {
                            await bc.SendReply(reply.EndsWithI(" | ") ? reply.Substring(0, reply.Length - 3) : reply);
                        }
                    }

                    return;
                }
            }
            await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", player.Name);
        }
示例#10
0
        public static async Task ClanTop(CommandContext bc)
        {
            string clanInitials;
            string clanName;
            if (bc.Message.ContainsI("SS"))
            {
                clanInitials = "SS";
                clanName = "Supreme Skillers";
            }
            else if (bc.Message.ContainsI("TS"))
            {
                clanInitials = "TS";
                clanName = "True Skillers";
            }
            else
            {
                clanInitials = "PT";
                clanName = "Portugal";
            }

            var rsn = await bc.GetPlayerName(bc.From.Nickname);
            string skill = null,
                   activity = null;
            int rank = 0;
            bool IsIndividual = false;

            // get @exp
            bool exp = false;
            if (bc.Message.Contains(" @exp") || bc.Message.Contains(" @xp"))
            {
                exp = true;
                bc.Message = bc.Message.Replace(" @exp", string.Empty);
                bc.Message = bc.Message.Replace(" @xp", string.Empty);
            }

            // Create a list of Clan players
            var clanPlayers = await Players.FromClan(clanInitials);

            // Parse command arguments
            if (bc.MessageTokens.Length == 1)
            {
                // !ClanTop
                IsIndividual = true;
            }
            else if (Bot.Activity.TryParse(bc.MessageTokens[1], ref activity) || Skill.TryParse(bc.MessageTokens[1], ref skill))
            {
                // !ClanTop Skill/Activity
                rank = 1;

                // Clean and sort clan members by specified skill
                if (activity == null)
                {
                    var players = clanPlayers.Where(p => p.Skills[skill].Exp > 0);
                    players = exp
                        ? players.OrderByDescending(p => p.Skills[skill].Exp).ThenBy(p => p.Skills[skill].Rank)
                        : players.OrderBy(p => p.Skills[skill]);
                    clanPlayers = players.ToList();
                }
                else
                {
                    clanPlayers = clanPlayers.Where(p => p.Activities[activity].Score > 0).OrderBy(p => p.Activities[activity]).ToList();
                }

                if (bc.MessageTokens.Length > 2)
                {
                    if (int.TryParse(bc.MessageTokens[2], out rank))
                    {
                        // !ClanTop Skill/Activity Rank
                    }
                    else if (bc.MessageTokens.Length == 3 && bc.MessageTokens[2].ToUpperInvariant() == "@LAST")
                    {
                        // !ClanTop Skill/Activity @last
                        rank = clanPlayers.Count;
                    }
                    else
                    {
                        // !ClanTop Skill/Activity RSN
                        rsn = await bc.GetPlayerName(bc.MessageTokens.Join(2));
                        var indexOfPlayer = clanPlayers.FindIndex(p => p.Name.EqualsI(rsn));
                        if (indexOfPlayer != -1)
                        {
                            rank = indexOfPlayer + 1;
                        }
                    }
                }
            }
            else
            {
                // !ClanTop RSN
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
                IsIndividual = true;
            }

            if (IsIndividual)
            {
                var player = clanPlayers.FirstOrDefault(p => p.Name.EqualsI(rsn));
                if (player != null)
                {
                    // individual skill ranks
                    string reply = @"[{0}] \b{1}\b skill ranks:".FormatWith(clanInitials, rsn);
                    foreach (var s in player.Skills.Values.Where(s => s.Exp > 0))
                    {
                        var indexOfPlayer = clanPlayers.OrderBy(p => p.Skills[s.Name]).IndexOf(player);
                        reply += @" \c7#{0}\c {1};".FormatWith(indexOfPlayer + 1, s.ShortName);
                    }
                    await bc.SendReply(reply);

                    // individual activity ranks
                    bool ranked = false;
                    reply = @"[{0}] \b{1}\b activity ranks:".FormatWith(clanInitials, rsn);
                    foreach (var a in player.Activities.Values.Where(a => a.Score > 0))
                    {
                        ranked = true;

                        var indexOfPlayer = clanPlayers.OrderBy(p => p.Activities[a.Name]).IndexOf(player);
                        reply += @" \c7#{0}\c {1};".FormatWith(indexOfPlayer + 1, a.Name);
                    }
                    if (ranked)
                    {
                        await bc.SendReply(reply);
                    }
                }
                else
                {
                    await bc.SendReply(@"\b{0}\b isn't at {1}.", rsn, clanName);
                }
                return;
            }
            
            // Get input player rank
            var inputPlayerName = await bc.GetPlayerName(bc.From.Nickname);
            var inputPlayerRank = clanPlayers.FindIndex(p => p.Name.EqualsI(inputPlayerName)) + 1;

            // fix rank
            if (rank < 1)
            {
                rank = 1;
            }
            else if (rank > clanPlayers.Count)
            {
                rank = clanPlayers.Count;
            }

            int MinRank = rank - 6;
            if (MinRank < 0)
            {
                MinRank = 0;
            }
            else if (MinRank > clanPlayers.Count - 11)
            {
                MinRank = clanPlayers.Count - 11;
            }

            var skillFormat = exp ? "e" : "l";

            if (activity == null)
            {
                if (clanPlayers.Count > 0)
                {
                    var reply = @"[{0}] \u{1}\u ranking:".FormatWith(clanInitials, skill.ToLowerInvariant());
                    if (inputPlayerRank > 0 && inputPlayerRank <= MinRank)
                    {
                        reply += @" \c7#{0}\c \u{1}\u ({2});".FormatWith(inputPlayerRank, clanPlayers[inputPlayerRank - 1].Name, clanPlayers[inputPlayerRank - 1].Skills[skill].ToStringI(skillFormat));
                    }

                    for (int i = MinRank; i < Math.Min(MinRank + 11, clanPlayers.Count); i++)
                    {
                        reply += " ";
                        if (i == rank - 1)
                        {
                            reply += @"\b";
                        }
                        reply += @"\c7#{0}\c ".FormatWith(i + 1);
                        if (i == inputPlayerRank - 1)
                        {
                            reply += @"\u";
                        }
                        reply += clanPlayers[i].Name;
                        if (i == inputPlayerRank - 1)
                        {
                            reply += @"\u";
                        }

                        reply += " (" + clanPlayers[i].Skills[skill].ToStringI(skillFormat) + ")";

                        if (i == rank - 1)
                        {
                            reply += @"\b";
                        }
                        reply += ";";
                    }

                    if (inputPlayerRank > 0 && inputPlayerRank > MinRank + 11)
                    {
                        reply += @" \c7#{0}\c \u{1}\u ({2:e});".FormatWith(inputPlayerRank, clanPlayers[inputPlayerRank - 1].Name, clanPlayers[inputPlayerRank - 1].Skills[skill].ToStringI(skillFormat));
                    }

                    await bc.SendReply(reply);
                }
                else
                {
                    await bc.SendReply(clanName + " don't have any member ranked at this skill.");
                }
            }
            else
            {
                if (clanPlayers.Count > 0)
                {
                    var reply = @"[{0}] \u{1}\u ranking:".FormatWith(clanInitials, activity.ToLowerInvariant());
                    if (inputPlayerRank > 0 && inputPlayerRank <= MinRank)
                    {
                        reply += @" \c7#{0}\c \u{1}\u ({2});".FormatWith(inputPlayerRank, clanPlayers[inputPlayerRank - 1].Name, clanPlayers[inputPlayerRank - 1].Activities[activity].Score);
                    }

                    for (int i = MinRank; i < Math.Min(MinRank + 11, clanPlayers.Count); i++)
                    {
                        reply += " ";
                        if (i == rank - 1)
                        {
                            reply += @"\b";
                        }
                        reply += @"\c7#{0}\c ".FormatWith(i + 1);
                        if (i == inputPlayerRank - 1)
                        {
                            reply += @"\u";
                        }
                        reply += clanPlayers[i].Name;
                        if (i == inputPlayerRank - 1)
                        {
                            reply += @"\u";
                        }
                        reply += " (" + clanPlayers[i].Activities[activity].Score + ")";
                        if (i == rank - 1)
                        {
                            reply += @"\b";
                        }
                        reply += ";";
                    }

                    if (inputPlayerRank > 0 && inputPlayerRank > MinRank + 11)
                    {
                        reply += @" \c07#" + inputPlayerRank + @"\c \u" + clanPlayers[inputPlayerRank - 1].Name + @"\u (" + clanPlayers[inputPlayerRank - 1].Activities[activity].Score + ");";
                    }

                    await bc.SendReply(reply);
                }
                else
                {
                    await bc.SendReply(clanName + " don't have any member ranked at this activity.");
                }
            }
        }
示例#11
0
        private static async Task _SetGoal(CommandContext bc)
        {
            if (bc.MessageTokens.Length < 3)
            {
                await bc.SendReply("Syntax: !set goal <skill> [goal]");
                return;
            }

            string skill = null;
            string goal = null;
            if (Skill.TryParse(bc.MessageTokens[2], ref skill))
            {
                if (bc.MessageTokens.Length > 3)
                {
                    // !set goal <skill> <goal>
                    goal = bc.MessageTokens[3];
                } // else { // !set goal <skill> }
            }
            else if (bc.MessageTokens.Length > 3 && Skill.TryParse(bc.MessageTokens[3], ref skill))
            {
                // !set goal <goal> <skill>
                goal = bc.MessageTokens[2];
            }
            else
            {
                await bc.SendReply("Error: Invalid skill name.");
                return;
            }

            if (goal == null)
            {
                // Get goal from database
                goal = await Database.GetStringParameter("users", "goals", "fingerprint='" + bc.From.FingerPrint + "'", skill, "nl");
            }
            else if (!Regex.Match(goal, @"n(?:l|r)|r?\d+(?:\.\d+)?(?:m|k)?").Success)
            {
                await bc.SendReply("Error: Invalid goal.");
                return;
            }

            // Add this player to database if he never set a default name.
            if (await Database.Lookup<long>("COUNT(*)", "users", "fingerprint=@fp", new[] { new MySqlParameter("@fp", bc.From.FingerPrint) }) < 1)
            {
                await Database.Insert("users", "fingerprint", bc.From.FingerPrint, "rsn", await bc.GetPlayerName(bc.From.Nickname));
            }

            if (goal.EqualsI("nl"))
            {
                await bc.SendReply(@"Your goal for \b{0}\b is currently set to \unext level\u.", skill);
            }
            else if (goal.EqualsI("nr"))
            {
                await bc.SendReply(@"Your goal for \b{0}\b is currently set to \unext rank\u.", skill);
            }
            else if (goal.StartsWithI("r"))
            {
                int goalRank = goal.Substring(1).ToInt32();
                if (goalRank > 0 && goalRank <= 2000000)
                {
                    await bc.SendReply(@"Your goal for \b{0}\b is currently set to \urank {1}\u.", skill, goalRank.ToShortString(1));
                    goal = "r" + goalRank.ToStringI();
                }
                else
                {
                    await bc.SendReply(@"Your goal for \b{0}\b is currently set to \unext rank\u.", skill);
                    goal = "nr";
                }
            }
            else
            {
                int goalLevel = goal.ToInt32();
                if (goalLevel > 1 && goalLevel < 127)
                {
                    await bc.SendReply(@"Your goal for \b{0}\b is currently set to \ulevel {1}\u.", skill, goalLevel);
                    goal = goalLevel.ToStringI();
                }
                else if (goalLevel == 127)
                {
                    await bc.SendReply(@"Your goal for \b{0}\b is currently set to \u200m exp\u.", skill);
                    goal = goalLevel.ToStringI();
                }
                else if (goalLevel > 127 && goalLevel <= 200000000)
                {
                    await bc.SendReply(@"Your goal for \b{0}\b is currently set to \u{1} exp\u.", skill, goalLevel.ToShortString(1));
                    goal = goalLevel.ToStringI();
                }
                else
                {
                    await bc.SendReply(@"Your goal for \b{0}\b is currently set to \unext level\u.", skill);
                    goal = "nl";
                }
            }
            await Database.SetStringParameter("users", "goals", "fingerprint='" + bc.From.FingerPrint + "'", skill, goal);
        }
示例#12
0
        private static async Task _SetSkill(CommandContext bc)
        {
            if (bc.MessageTokens.Length < 3)
            {
                await bc.SendReply("Syntax: !set skill <skill>");
                return;
            }

            if (bc.MessageTokens[2].ToLowerInvariant() == "on" || bc.MessageTokens[2].ToLowerInvariant() == "off")
            {
                await _SetSkillToggle(bc);
                return;
            }

            string skill = Skill.OVER;
            if (!Skill.TryParse(bc.MessageTokens[2], ref skill))
            {
                await bc.SendReply("Error: Invalid skill name.");
                return;
            }

            // Add this player to database if he never set a default name.
            if (await Database.Lookup<long>("COUNT(*)", "users", "fingerprint=@fp", new[] { new MySqlParameter("@fp", bc.From.FingerPrint) }) < 1)
            {
                await Database.Insert("users", "fingerprint", bc.From.FingerPrint, "rsn", await bc.GetPlayerName(bc.From.Nickname));
            }

            await Database.Update("users", "fingerprint='" + bc.From.FingerPrint + "'", "skill", skill);
            await bc.SendReply(@"Your default skill is currently set to \b{0}\b.", skill);
        }
示例#13
0
        private static async Task _SetSkillToggle(CommandContext bc)
        {
            if (bc.MessageTokens.Length < 3 || (bc.MessageTokens[2].ToLowerInvariant() != "on" && bc.MessageTokens[2].ToLowerInvariant() != "off"))
            {
                await bc.SendReply("Syntax: !set @ <on|off>");
                return;
            }
            string state = bc.MessageTokens[2].ToLowerInvariant();

            // Add this player to database if he never set a default name.
            if (await Database.Lookup<long>("COUNT(*)", "users", "fingerprint=@fp", new[] { new MySqlParameter("@fp", bc.From.FingerPrint) }) < 1)
            {
                await Database.Insert("users", "fingerprint", bc.From.FingerPrint, "rsn", await bc.GetPlayerName(bc.From.Nickname));
            }
            string publicSkill = "1";
            if (state == "off")
            {
                publicSkill = "0";
            }
            await Database.Update("users", "fingerprint='" + bc.From.FingerPrint + "'", "publicSkill", publicSkill);
            await bc.SendReply("Your public trigger-only command have been turned " + state + ".");
        }
示例#14
0
        private static async Task _SetSpeed(CommandContext bc)
        {
            if (bc.MessageTokens.Length < 4)
            {
                await bc.SendReply("Syntax: !set speed <skill> <average exp. per hour>");
                return;
            }

            string skill = Skill.OVER;
            if (!Skill.TryParse(bc.MessageTokens[2], ref skill))
            {
                await bc.SendReply("Error: Invalid skill name.");
                return;
            }

            string speed = bc.MessageTokens[3].ToLowerInvariant();
            if (!Regex.Match(speed, @"\d+(?:\.\d+)?(?:m|k)?").Success)
            {
                await bc.SendReply("Error: Invalid average exp. per hour.");
                return;
            }

            // Add this player to database if he never set a default name.
            if (await Database.Lookup<long>("COUNT(*)", "users", "fingerprint=@fp", new[] { new MySqlParameter("@fp", bc.From.FingerPrint) }) < 1)
            {
                await Database.Insert("users", "fingerprint", bc.From.FingerPrint, "rsn", await bc.GetPlayerName(bc.From.Nickname));
            }

            int speedValue = speed.ToInt32();
            await Database.SetStringParameter("users", "speeds", "fingerprint='" + bc.From.FingerPrint + "'", skill, speedValue.ToStringI());

            if (speedValue > 0)
            {
                await bc.SendReply(@"Your speed for \b{0}\b is currently set to \u{1} average exp. per hour\u.", skill, speedValue.ToShortString(1));
            }
            else
            {
                await bc.SendReply(@"Your speed for \b{0}\b was deleted.", skill);
            }
        }
示例#15
0
        private static async Task _SetItem(CommandContext bc)
        {
            if (bc.MessageTokens.Length < 4)
            {
                await bc.SendReply("Syntax: !set item <skill> <item>");
                return;
            }

            string skill = Skill.OVER;
            if (!Skill.TryParse(bc.MessageTokens[2], ref skill))
            {
                await bc.SendReply("Error: Invalid skill name.");
                return;
            }

            string item = bc.MessageTokens.Join(3).Replace(";", string.Empty).ToLowerInvariant();

            // Add this player to database if he never set a default name.
            if (await Database.Lookup<long>("COUNT(*)", "users", "fingerprint=@fp", new[] { new MySqlParameter("@fp", bc.From.FingerPrint) }) < 1)
            {
                await Database.Insert("users", "fingerprint", bc.From.FingerPrint, "rsn", await bc.GetPlayerName(bc.From.Nickname));
            }

            await Database.SetStringParameter("users", "items", "fingerprint='" + bc.From.FingerPrint + "'", skill, item);
            await bc.SendReply(@"Your default item for \b{0}\b is currently set to \u{1}\u.", skill, item);
        }
示例#16
0
        public static async Task Stats(CommandContext bc)
        {
            // get @next
            var nextMatch = _nextRegex.Match(bc.Message);
            if (nextMatch.Success)
            {
                bc.Message = bc.Message.Replace(nextMatch.Value, string.Empty);
            }

            // get @experience
            var expMatch = _expRegex.Match(bc.Message);
            if (expMatch.Success)
            {
                bc.Message = bc.Message.Replace(expMatch.Value, string.Empty);
            }

            // get @rank
            var rankMatch = _rankRegex.Match(bc.Message);
            if (rankMatch.Success)
            {
                bc.Message = bc.Message.Replace(rankMatch.Value, string.Empty);
            }

            // get @virtuallevel
            var virtualMatch = _virtualRegex.Match(bc.Message);
            if (virtualMatch.Success)
            {
                bc.Message = bc.Message.Replace(virtualMatch.Value, string.Empty);
            }

            // get <
            var lessThan = 0;
            var lessThanMatch = _lessThanRegex.Match(bc.Message);
            if (lessThanMatch.Success)
            {
                lessThan = int.Parse(lessThanMatch.Groups[1].Value, CultureInfo.InvariantCulture);
                switch (lessThanMatch.Groups[2].Value)
                {
                    case "m":
                        lessThan *= 1000000;
                        break;
                    case "k":
                        lessThan *= 1000;
                        break;
                }

                if (lessThan < 127)
                {
                    lessThan = lessThan.ToExp();
                }

                bc.Message = bc.Message.Replace(lessThanMatch.Value, string.Empty);
            }

            // get >
            var greaterThan = 0;
            var greaterThanMatch = _greaterThanRegex.Match(bc.Message);
            if (greaterThanMatch.Success)
            {
                greaterThan = int.Parse(greaterThanMatch.Groups[1].Value, CultureInfo.InvariantCulture);
                switch (greaterThanMatch.Groups[2].Value)
                {
                    case "m":
                        greaterThan *= 1000000;
                        break;
                    case "k":
                        greaterThan *= 1000;
                        break;
                }

                if (greaterThan < 126)
                {
                    greaterThan = (greaterThan + 1).ToExp();
                }

                bc.Message = bc.Message.Replace(greaterThanMatch.Value, string.Empty);
            }

            // get player
            var player = await Player.FromHiscores(await bc.GetPlayerName(bc.MessageTokens.Length == 1 ? bc.From.Nickname : bc.MessageTokens.Join(1)));
            if (!player.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", player.Name);
                return;
            }

            // !all @next
            if (nextMatch.Success)
            {
                var i = 0;
                await bc.SendReply(from skill in player.Skills.SortedByExpToNextVLevel
                             group skill by i++ / 13
                             into skills
                             select skills.Aggregate(
                                 new StringBuilder(512).AppendFormat(@"\b{0}\b exp. to next level:", player.Name),
                                 (sb, skill) => sb.AppendFormat(@"\c{0} {1:N0}\c {2};", skill.VLevel >= skill.MaxLevel ? 4 : 3, skill.ExpToVLevel, skill.Name)
                                 ));
                return;
            }
            
            // select non meta player skills
            var playerSkills = player.Skills.Values.Where(s => s.Name != Skill.OVER && s.Name != Skill.COMB).ToList();

            // calculate overall max level and exp
            var maxOverallLevel = 0;
            var maxOverallExp = 0L;
            if (virtualMatch.Success)
            {
                maxOverallLevel = 126 * playerSkills.Count;
                maxOverallExp = 200000000L * playerSkills.Count;
            }
            else
            {
                foreach (var skill in playerSkills)
                {
                    maxOverallLevel += skill.MaxLevel;
                    maxOverallExp += skill.MaxLevel.ToExp();
                }
            }

            // calculate overall and average levels
            var overallLevel = virtualMatch.Success ? playerSkills.Sum(skill => skill.VLevel) : player.Skills[Skill.OVER].Level;
            var avgSkillLevel = (double) overallLevel / playerSkills.Count;
            var averageExp = player.Skills[Skill.OVER].Exp / playerSkills.Count;

            var reply = new StringBuilder(512)
                .AppendFormat(@"\b{0}\b \c7{1:n}\c | level:\c7 {2:N0}\c (\c07{3:N1}\c avg) | exp:\c7 {1:e}\c (\c07{4:0.#%}\c of {5}) | rank:\c7 {1:R}\c", player.Name, player.Skills[Skill.OVER], overallLevel, avgSkillLevel, (double) player.Skills[Skill.OVER].Exp / maxOverallExp, maxOverallLevel);

            // add SS rank if applicable
            var ssPlayers = (await Players.FromClan("SS")).OrderBy(p => p.Skills[Skill.OVER]);
            var ssRank = ssPlayers.FindIndex(p => p.Name.EqualsI(player.Name));
            if (ssRank != -1)
            {
                reply.AppendFormat(@" (SS rank: \c07{0}\c)", ssRank + 1);
            }

            // output overall information
            await bc.SendReply(reply);

            // output skills
            var format = @" {2}\c{1:00}{0:r";
            if (expMatch.Success)
            {
                format += 'e';
            }
            else if (virtualMatch.Success)
            {
                format += 'v';
            }
            else if (!rankMatch.Success)
            {
                format += 'l';
            }
            format += @"}\c {0:n}{2};";

            var avgExpThreshold = averageExp / 5;
            var highestExp = playerSkills.Max(s => s.Exp);

            var filteredSkills = playerSkills.Where(s => (lessThan == 0 || s.Exp < lessThan) && (greaterThan == 0 || s.Exp > greaterThan)).ToList();

            await bc.SendReply(filteredSkills.Where(s => s.IsCombat).Concat(player.Skills[Skill.COMB]).Aggregate(
                new StringBuilder(@"\uCombat skills\u:", 512),
                (sb, s) => sb.AppendFormat(format, s, s.Exp > averageExp + avgExpThreshold ? 3 : (s.Exp < averageExp - avgExpThreshold ? 4 : 7), s.Exp == highestExp ? @"\u" : string.Empty)
                ).AppendFormat(@" (\c7{0}\c)", player.CombatClass));

            await bc.SendReply(filteredSkills.Where(s => !s.IsCombat).AggregateOrDefault(
                new StringBuilder(@"\uOther skills\u:", 512),
                (sb, s) => sb.AppendFormat(format, s, s.Exp > averageExp + avgExpThreshold ? 3 : (s.Exp < averageExp - avgExpThreshold ? 4 : 7), s.Exp == highestExp ? @"\u" : string.Empty)
                ));

            // output activities
            if (lessThan == 0 && greaterThan == 0)
            {
                await bc.SendReply(player.Activities.Values.Where(a => a.Rank > 0).AggregateOrDefault(
                    new StringBuilder(@"\uActivities\u:", 512),
                    (sb, a) => sb.AppendFormat(@"\c7 {0:N0}\c {1};", rankMatch.Success ? a.Rank : a.Score, a.Name)
                    ));
            }
        }
示例#17
0
        public static async Task SlayerPercent(CommandContext bc)
        {
            // get rsn
            string rsn;
            if (bc.MessageTokens.Length > 1)
            {
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
            }
            else
            {
                rsn = await bc.GetPlayerName(bc.From.Nickname);
            }

            var p = await Player.FromHiscores(rsn);
            if (!p.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                return;
            }

            long hits_exp_gained = p.Skills[Skill.HITP].Exp - 1154;
            double expected_max_slayer_exp = hits_exp_gained * 3.0 / 4.0;

            await bc.SendReply(@"\b{0}\b \c07{1:0.##}% - {2:0.##}%\c of combat exp. is slayer based, with \c07{3:N0}\c combat slayer exp. and \c07{4:N0}\c combat total exp. (This percentage isn't accurate, mostly because of monster hp regeneration ratio and cannon slayering.)", rsn, (double) p.Skills[Skill.SLAY].Exp / expected_max_slayer_exp * 100.0, (double) p.Skills[Skill.SLAY].Exp / (expected_max_slayer_exp - ((double) hits_exp_gained / 133.0)) * 100.0, (double) p.Skills[Skill.SLAY].Exp * 16.0 / 3.0, hits_exp_gained + hits_exp_gained * 3);
        }
示例#18
0
        public static async Task Performance(CommandContext bc)
        {
            bool showAll = false;
            if (bc.Message.Contains(" @all"))
            {
                showAll = true;
                bc.Message = bc.Message.Replace(" @all", string.Empty);
            }

            // get rsn
            string rsn;
            if (bc.MessageTokens.Length > 1)
            {
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
            }
            else
            {
                rsn = await bc.GetPlayerName(bc.From.Nickname);
            }

            // get this player last update time
            DateTime lastupdate;
            var dblastupdate = await Database.LastUpdate(rsn);
            if (dblastupdate == null || dblastupdate.Length < 8)
            {
                lastupdate = DateTime.UtcNow.AddHours(-DateTime.UtcNow.Hour + 6).AddMinutes(-DateTime.UtcNow.Minute).AddSeconds(-DateTime.UtcNow.Second);
                if (DateTime.UtcNow.Hour >= 0 && DateTime.UtcNow.Hour < 6)
                {
                    lastupdate = lastupdate.AddDays(-1);
                }
            }
            else
            {
                lastupdate = dblastupdate.ToDateTime();
            }

            // get performance interval
            int days;
            string interval;
            DateTime firstday,
                     lastday;
            if (bc.MessageTokens[0].Contains("yesterday") || bc.MessageTokens[0].Contains("yday"))
            {
                interval = "Yesterday";
                lastday = lastupdate;
                firstday = lastday.AddDays(-1);
                days = 1;
            }
            else if (bc.MessageTokens[0].Contains("lastweek") | bc.MessageTokens[0].Contains("lweek"))
            {
                interval = "Last week";
                lastday = lastupdate.AddDays(-((int) lastupdate.DayOfWeek));
                firstday = lastday.AddDays(-7);
                days = 7;
            }
            else if (bc.MessageTokens[0].Contains("lastmonth") | bc.MessageTokens[0].Contains("lmonth"))
            {
                interval = "Last month";
                lastday = lastupdate.AddDays(1 - lastupdate.Day);
                firstday = lastday.AddMonths(-1);
                days = (lastday - firstday).Days;
            }
            else if (bc.MessageTokens[0].Contains("lastyear") | bc.MessageTokens[0].Contains("lyear"))
            {
                interval = "Last year";
                lastday = lastupdate.AddDays(1 - lastupdate.DayOfYear);
                firstday = lastday.AddYears(-1);
                days = (lastday - firstday).Days;
            }
            else if (bc.MessageTokens[0].Contains("week"))
            {
                interval = "Week";
                firstday = lastupdate.AddDays(-((int) lastupdate.DayOfWeek));
                lastday = DateTime.MaxValue;
                days = (int) lastupdate.DayOfWeek + 1;
            }
            else if (bc.MessageTokens[0].Contains("month"))
            {
                interval = "Month";
                firstday = lastupdate.AddDays(1 - lastupdate.Day);
                lastday = DateTime.MaxValue;
                days = lastupdate.Day;
            }
            else if (bc.MessageTokens[0].Contains("year"))
            {
                interval = "Year";
                firstday = lastupdate.AddDays(1 - lastupdate.DayOfYear);
                lastday = DateTime.MaxValue;
                days = lastupdate.DayOfYear;
            }
            else if (bc.MessageTokens[0].Contains("today"))
            {
                interval = "Today";
                firstday = lastupdate;
                lastday = DateTime.MaxValue;
                days = 1;
            }
            else
            {
                Match M = Regex.Match(bc.MessageTokens[0], "last(\\d+)days");
                if (M.Success)
                {
                    days = int.Parse(M.Groups[1].Value, CultureInfo.InvariantCulture);
                    interval = "Last " + days + " days";
                    lastday = lastupdate;
                    firstday = lastday.AddDays(-days);
                }
                else
                {
                    return;
                }
            }

            // Get old player 
            var PlayerOld = await Player.FromDatabase(rsn, firstday);
            if (!PlayerOld.Ranked)
            {
                // Get data from RuneScript
                PlayerOld = new Player(rsn, (int) (DateTime.UtcNow - firstday).TotalSeconds);
                await bc.SendReply(@"\c07{0}\c information retrieved from RuneScript database. (This data may not be 100% accurate)", firstday.ToStringI("yyyy/MMM/dd"));
                if (!PlayerOld.Ranked)
                {
                    await bc.SendReply(@"\b{0}\b wasn't being tracked on \c07{1}\c.", rsn, firstday.ToStringI("yyyy/MMM/dd"));
                    return;
                }
                foreach (Skill skill in PlayerOld.Skills.Values)
                {
                    PlayerOld.Skills[skill.Name].Level = Math.Max(0, skill.Level);
                }
            }

            // Get new player
            Player PlayerNew;
            if (lastday == DateTime.MaxValue)
            {
                PlayerNew = await Player.FromHiscores(rsn);
            }
            else
            {
                PlayerNew = await Player.FromDatabase(rsn, lastday);
            }
            if (!PlayerNew.Ranked)
            {
                if (lastday == DateTime.MaxValue)
                {
                    await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                    return;
                }

                // Get data from RuneScript
                PlayerNew = new Player(rsn, (int) (DateTime.UtcNow - lastday).TotalSeconds);
                await bc.SendReply(@"\c07{0}\c information retrieved from RuneScript database. (This data may not be 100% accurate)", lastday.ToStringI("yyyy/MMM/dd"));
                if (!PlayerNew.Ranked)
                {
                    await bc.SendReply(@"\b{0}\b wasn't being tracked on \c07{1}\c.", rsn, lastday.ToStringI("yyyy/MMM/dd"));
                    return;
                }
            }

            // 1st line: overall / combat
            string ReplyMsg = @"\b{0}\b \u{1}\u skills:".FormatWith(rsn, interval.ToLowerInvariant());
            Skill OverallDif = PlayerNew.Skills[Skill.OVER] - PlayerOld.Skills[Skill.OVER];
            if (OverallDif.Exp <= 0)
            {
                await bc.SendReply(@"No performance for \b{0}\b within this period.", rsn);
            }
            else
            {
                Skill CombatDif = PlayerNew.Skills[Skill.COMB] - PlayerOld.Skills[Skill.COMB];

                string DifLevel = string.Empty;
                if (OverallDif.Level > 0)
                {
                    DifLevel = @" [\b+{0}\b]".FormatWith(OverallDif.Level);
                }
                if (days == 1)
                {
                    ReplyMsg += @" \c07Overall\c lvl {0} \c03+{1}\c xp (Avg. hourly exp.: \c07{2}\c)".FormatWith(PlayerNew.Skills[Skill.OVER].Level + DifLevel, OverallDif.Exp.ToShortString(1), (OverallDif.Exp / 24.0).ToShortString(0));
                }
                else
                {
                    ReplyMsg += @" \c07Overall\c lvl {0} \c03+{1}\c xp (Avg. daily exp.: \c07{2}\c)".FormatWith(PlayerNew.Skills[Skill.OVER].Level + DifLevel, OverallDif.Exp.ToShortString(1), (OverallDif.Exp / (double) days).ToShortString(0));
                }
                DifLevel = string.Empty;
                if (CombatDif.Level > 0)
                {
                    DifLevel = @" [\b+{0}\b]".FormatWith(CombatDif.Level);
                }
                ReplyMsg += @"; \c07Combat\c lvl {0} \c03+{1}\c xp (\c07{2}%\c)".FormatWith(PlayerNew.Skills[Skill.COMB].Level + DifLevel, CombatDif.Exp.ToShortString(1), (CombatDif.Exp / (double) OverallDif.Exp * 100.0).ToShortString(1));

                ReplyMsg += @"; Interval: \c07{0}\c -> \c07{1}\c".FormatWith(firstday.ToStringI("yyyy/MMM/dd"), lastday == DateTime.MaxValue ? "Now" : lastday.ToStringI("yyyy/MMM/dd"));
                await bc.SendReply(ReplyMsg);

                // 2nd line: skills list
                List<Skill> SkillsDif = (from SkillNow in PlayerNew.Skills.Values
                                         where SkillNow.Name != Skill.OVER && SkillNow.Name != Skill.COMB
                                         select SkillNow - PlayerOld.Skills[SkillNow.Name]).ToList();
                SkillsDif.Sort();

                int skillLength = showAll ? SkillsDif.Count : 10;
                bool has_performance = false;
                ReplyMsg = @"\b{0}\b \u{1}\u skills:".FormatWith(rsn, interval.ToLowerInvariant());
                for (int i = 0; i < skillLength; i++)
                {
                    if (SkillsDif[i].Exp > 0)
                    {
                        has_performance = true;
                        DifLevel = string.Empty;
                        if (SkillsDif[i].Level > 0)
                        {
                            DifLevel = @" [\b+{0}\b]".FormatWith(SkillsDif[i].Level);
                        }
                        ReplyMsg += @" \c07{0}\c lvl {1} \c3+{2}\c xp;".FormatWith(SkillsDif[i].Name, PlayerNew.Skills[SkillsDif[i].Name].Level + DifLevel, SkillsDif[i].Exp.ToShortString(1));
                    }
                    if ((i + 1) % 10 == 0)
                    {
                        await bc.SendReply(ReplyMsg);
                        has_performance = false;
                        ReplyMsg = @"\b{0}\b \u{1}\u skills:".FormatWith(rsn, interval.ToLowerInvariant());
                    }
                }
                if (has_performance)
                {
                    await bc.SendReply(ReplyMsg);
                }

                // 3rd line: activities list
                List<Activity> activitiesDelta = (from newActivity in PlayerNew.Activities.Values
                                                  where PlayerOld.Activities.ContainsKey(newActivity.Name)
                                                  select newActivity - PlayerOld.Activities[newActivity.Name]).ToList();
                activitiesDelta.Sort();

                if (activitiesDelta.Count > 0)
                {
                    has_performance = false;
                    ReplyMsg = @"\b{0}\b \u{1}\u activities:".FormatWith(rsn, interval.ToLowerInvariant());
                    foreach (Activity t in activitiesDelta)
                    {
                        if (t.Score > 0)
                        {
                            has_performance = true;
                            ReplyMsg += @" \c07{0}\c \c3+{1}\c score;".FormatWith(t.Name, t.Score);
                        }
                    }
                    if (has_performance)
                    {
                        await bc.SendReply(ReplyMsg);
                    }
                }
            }
        }
示例#19
0
        public static async Task SoulWars(CommandContext bc)
        {
            // get rsn
            string rsn = string.Empty;
            string skill = string.Empty;
            int level = 0;
            if (bc.MessageTokens.Length == 2)
            {
                rsn = await bc.GetPlayerName(bc.From.Nickname);
                Skill.TryParse(bc.MessageTokens[1], ref skill);
            }
            else if (bc.MessageTokens.Length == 3)
            {
                if (int.TryParse(bc.MessageTokens[1], out level))
                {
                    Skill.TryParse(bc.MessageTokens[2], ref skill);
                }
                else if (int.TryParse(bc.MessageTokens[2], out level))
                {
                    Skill.TryParse(bc.MessageTokens[1], ref skill);
                }
                else
                {
                    if (Skill.TryParse(bc.MessageTokens[1], ref skill))
                    {
                        rsn = await bc.GetPlayerName(bc.MessageTokens[2]);
                    }
                    else if (Skill.TryParse(bc.MessageTokens[2], ref skill))
                    {
                        rsn = await bc.GetPlayerName(bc.MessageTokens[1]);
                    }
                }
            }
            else if (bc.MessageTokens.Length > 3)
            {
                if (Skill.TryParse(bc.MessageTokens[1], ref skill))
                {
                    rsn = await bc.GetPlayerName(bc.MessageTokens.Join(2).Trim());
                }
                else if (Skill.TryParse(bc.MessageTokens[bc.MessageTokens.Length - 1], ref skill))
                {
                    bc.MessageTokens[bc.MessageTokens.Length - 1] = string.Empty;
                    rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1).Trim());
                }
            }
            if (string.IsNullOrEmpty(skill) || (string.IsNullOrEmpty(rsn) && level == 0))
            {
                await bc.SendReply("Syntax: !soulwars <level> <skill>");
                return;
            }

            if (!string.IsNullOrEmpty(rsn))
            {
                var p = await Player.FromHiscores(rsn);
                if (!p.Ranked)
                {
                    await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                    return;
                }
                Skill skillInfo = p.Skills[skill];
                level = skillInfo.Level;
            }

            switch (skill)
            {
                case Skill.ATTA:
                case Skill.STRE:
                case Skill.DEFE:
                case Skill.HITP:
                case Skill.RANG:
                case Skill.MAGI:
                case Skill.PRAY:
                case Skill.SLAY:
                    int exp = Utils.SoulWarsExpPerZeal(skill, level);
                    await bc.SendReply(@"For each point at level \c07{0}\c you will gain \c07{1:N0} {2}\c experience.", level, exp, skill);
                    break;
                default:
                    await bc.SendReply("You can only calculate experience for Attack, Strength, Defence, Constitution, Prayer and Slayer at the moment.");
                    break;
            }
        }
示例#20
0
        public static async Task Compare(CommandContext bc)
        {
            if (bc.MessageTokens.Length == 1)
            {
                await bc.SendReply("Syntax: !compare [skill] <player1> [player2]");
                return;
            }

            string skill1 = null,
                   activity1 = null;
            string rsn1,
                   rsn2;
            if (Skill.TryParse(bc.MessageTokens[1], ref skill1))
            {
                if (bc.MessageTokens.Length == 3)
                {
                    // !compare <skill> <player2>
                    rsn1 = await bc.GetPlayerName(bc.From.Nickname);
                    rsn2 = await bc.GetPlayerName(bc.MessageTokens[2]);
                }
                else if (bc.MessageTokens.Length > 3)
                {
                    // !compare <skill> <player1> <player2>
                    rsn1 = await bc.GetPlayerName(bc.MessageTokens[2]);
                    rsn2 = await bc.GetPlayerName(bc.MessageTokens.Join(3));
                }
                else
                {
                    // !compare <player2>
                    skill1 = Skill.OVER;
                    rsn1 = await bc.GetPlayerName(bc.From.Nickname);
                    rsn2 = await bc.GetPlayerName(bc.MessageTokens[1]);
                }
            }
            else if (Bot.Activity.TryParse(bc.MessageTokens[1], ref activity1))
            {
                if (bc.MessageTokens.Length == 3)
                {
                    // !compare <activity> <player2>
                    rsn1 = await bc.GetPlayerName(bc.From.Nickname);
                    rsn2 = await bc.GetPlayerName(bc.MessageTokens[2]);
                }
                else if (bc.MessageTokens.Length > 3)
                {
                    // !compare <activity> <player1> <player2>
                    rsn1 = await bc.GetPlayerName(bc.MessageTokens[2]);
                    rsn2 = await bc.GetPlayerName(bc.MessageTokens.Join(3));
                }
                else
                {
                    // !compare <player2>
                    skill1 = Skill.OVER;
                    rsn1 = await bc.GetPlayerName(bc.From.Nickname);
                    rsn2 = await bc.GetPlayerName(bc.MessageTokens[1]);
                }
            }
            else if (bc.MessageTokens.Length == 2)
            {
                // !compare <player2>
                skill1 = Skill.OVER;
                rsn1 = await bc.GetPlayerName(bc.From.Nickname);
                rsn2 = await bc.GetPlayerName(bc.MessageTokens[1]);
            }
            else
            {
                // !compare <player1> <player2>
                skill1 = Skill.OVER;
                rsn1 = await bc.GetPlayerName(bc.MessageTokens[1]);
                rsn2 = await bc.GetPlayerName(bc.MessageTokens.Join(2));
            }

            var p1 = await Player.FromHiscores(rsn1);
            if (!p1.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn1);
                return;
            }

            var p2 = await Player.FromHiscores(rsn2);
            if (!p2.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn2);
                return;
            }

            string reply;
            if (activity1 == null)
            {
                // compare skills
                Skill pskill1 = p1.Skills[skill1];
                Skill pskill2 = p2.Skills[skill1];

                if (pskill1.Level == pskill2.Level)
                {
                    reply = @"Both \b{0}\b and \b{1}\b have level \c07{2}\c".FormatWith(p1.Name, p2.Name, pskill1.Level);
                    if (pskill1.Exp == pskill2.Exp)
                    {
                        reply += @" and \c07{0:e}\c experience.".FormatWith(pskill1);
                    }
                    else if (pskill1.Exp > pskill2.Exp)
                    {
                        reply += @", but \b{0}\b has \c07{1:N0}\c more experience.".FormatWith(p1.Name, pskill1.Exp - pskill2.Exp);
                    }
                    else
                    {
                        reply += @", but \b{0}\b has \c07{1:N0}\c less experience.".FormatWith(p1.Name, pskill2.Exp - pskill1.Exp);
                    }
                }
                else if (pskill1.Level > pskill2.Level)
                {
                    reply = @"\b{0}\b has \c07{2}\c more level{3} than \b{1}\b.".FormatWith(p1.Name, p2.Name, pskill1.Level - pskill2.Level, pskill1.Level - pskill2.Level == 1 ? string.Empty : "s");
                    if (pskill1.Exp == pskill2.Exp)
                    {
                        reply += @", but both have \c07{0:e}\c experience.".FormatWith(pskill1);
                    }
                    else if (pskill1.Exp > pskill2.Exp)
                    {
                        reply += @" and has \c07{0:N0}\c more experience.".FormatWith(pskill1.Exp - pskill2.Exp);
                    }
                    else
                    {
                        reply += @", but \b{0}\b has \c07{1:N0}\c less experience.".FormatWith(p1.Name, pskill2.Exp - pskill1.Exp);
                    }
                }
                else
                {
                    reply = @"\b{0}\b has \c07{2}\c less level{3} than \b{1}\b.".FormatWith(p1.Name, p2.Name, pskill2.Level - pskill1.Level, pskill2.Level - pskill1.Level == 1 ? string.Empty : "s");
                    if (pskill1.Exp == pskill2.Exp)
                    {
                        reply += @", but both have \c07{0:e}\c experience.".FormatWith(pskill1);
                    }
                    else if (pskill1.Exp > pskill2.Exp)
                    {
                        reply += @", but \b{0}\b has \c07{1:N0}\c more experience.".FormatWith(p1.Name, pskill1.Exp - pskill2.Exp);
                    }
                    else
                    {
                        reply += @" and has \c07{0:N0}\c less experience.".FormatWith(pskill2.Exp - pskill1.Exp);
                    }
                }
                await bc.SendReply(reply);

                // get these players last update time
                var dblastupdate = await Database.LastUpdate(rsn1);
                if (dblastupdate != null && dblastupdate.Length == 8)
                {
                    p1 = await Player.FromDatabase(rsn1, dblastupdate.ToDateTime());
                    if (p1.Ranked)
                    {
                        dblastupdate = await Database.LastUpdate(rsn2);
                        if (dblastupdate != null && dblastupdate.Length == 8)
                        {
                            p2 = await Player.FromDatabase(rsn2, dblastupdate.ToDateTime());
                            if (p2.Ranked)
                            {
                                Skill skilldif1 = pskill1 - p1.Skills[skill1];
                                Skill skilldif2 = pskill2 - p2.Skills[skill1];
                                await bc.SendReply(@"Today \b{0}\b did \c07{1:e}\c exp. while \b{2}\b did \c07{3:e}\c exp.", rsn1, skilldif1, rsn2, skilldif2);
                            }
                        }
                    }
                }
            }
            else
            {
                // compare activities
                Activity p1Activity = p1.Activities[activity1];
                Activity p2Activity = p2.Activities[activity1];

                if (p1Activity.Rank == -1)
                {
                    await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn1);
                    return;
                }
                if (p2Activity.Rank == -1)
                {
                    await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn2);
                    return;
                }

                if (p1Activity.Score == p2Activity.Score)
                {
                    reply = @"Both \b{0}\b and \b{1}\b have \c07{2}\c score.".FormatWith(rsn1, rsn2, p1Activity.Score);
                }
                else if (p1Activity.Score > p2Activity.Score)
                {
                    reply = @"\b{0}\b has \c07{2}\c more score than \b{1}\b.".FormatWith(rsn1, rsn2, p1Activity.Score - p2Activity.Score);
                }
                else
                {
                    reply = @"\b{0}\b has \c07{2}\c less score than \b{1}\b.".FormatWith(rsn1, rsn2, p2Activity.Score - p1Activity.Score);
                }
                await bc.SendReply(reply);

                // get these players last update time
                var dblastupdate = await Database.LastUpdate(rsn1);
                if (dblastupdate != null && dblastupdate.Length == 8)
                {
                    p1 = await Player.FromDatabase(rsn1, dblastupdate.ToDateTime());
                    if (p1.Ranked && p1.Activities[activity1].Rank > 0)
                    {
                        dblastupdate = await Database.LastUpdate(rsn2);
                        if (dblastupdate != null && dblastupdate.Length == 8)
                        {
                            p2 = await Player.FromDatabase(rsn2, dblastupdate.ToDateTime());
                            if (p2.Ranked && p2.Activities[activity1].Rank > 0)
                            {
                                Activity p1ActivityDelta = p1Activity - p1.Activities[activity1];
                                Activity p2ActivityDelta = p2Activity - p2.Activities[activity1];
                                await bc.SendReply(@"Today \b{0}\b did \c07{1:s}\c score while \b{2}\b did \c07{3:s}\c score.", rsn1, p1ActivityDelta, rsn2, p2ActivityDelta);
                            }
                        }
                    }
                }
            }
        }
示例#21
0
        public static async Task End(CommandContext bc)
        {
            // get rsn
            string rsn = await bc.GetPlayerName(bc.From.Nickname);

            var p = await Player.FromHiscores(rsn);
            if (!p.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                return;
            }

            // get @set or @save
            bool set = bc.Message.ContainsI("@set") || bc.Message.ContainsI("@save");
            if (set)
            {
                bc.Message = Regex.Replace(bc.Message, @"\s*@s(?:et|ave)\s*", string.Empty);
            }

            // get timer name
            string name = string.Empty;
            int indexOfSharp = bc.Message.IndexOf('#');
            if (indexOfSharp > 0)
            {
                name = bc.Message.Substring(indexOfSharp + 1);
                bc.Message = bc.Message.Substring(0, indexOfSharp - 1);
            }

            var rs = await Database.FetchFirst("SELECT skill,exp,datetime FROM timers_exp WHERE fingerprint=@fingerprint AND name=@name LIMIT 1", new MySqlParameter("@fingerprint", bc.From.FingerPrint), new MySqlParameter("@name", name));
            if (rs != null)
            {
                string skill = rs.GetString(0);

                var gainedExp = p.Skills[skill].Exp - (uint) rs["exp"];
                TimeSpan time = DateTime.UtcNow - rs.GetString(2).ToDateTime();

                string reply = @"You gained \c07{0:N0}\c \u{1}\u exp in \c07{2}\c. That's \c07{3:N0}\c exp/h.".FormatWith(gainedExp, skill.ToLowerInvariant(), time.ToLongString(), (double) gainedExp / time.TotalHours);
                if (gainedExp > 0 && skill != Skill.OVER && skill != Skill.COMB && p.Skills[skill].VLevel < 126)
                {
                    reply += @" Estimated time to level up: \c07{0}\c".FormatWith(TimeSpan.FromSeconds(p.Skills[skill].ExpToVLevel / (gainedExp / time.TotalSeconds)).ToLongString());
                }
                await bc.SendReply(reply);

                if (gainedExp > 0)
                {
                    // Add this player to database if he never set a default name.
                    if (await Database.Lookup<long>("COUNT(*)", "users", "fingerprint=@fp", new[] { new MySqlParameter("@fp", bc.From.FingerPrint) }) < 1)
                    {
                        await Database.Insert("users", "fingerprint", bc.From.FingerPrint, "rsn", await bc.GetPlayerName(bc.From.Nickname));
                    }

                    // Set exp. made in an hour in this skill.
                    await Database.SetStringParameter("users", "speeds", "fingerprint='" + bc.From.FingerPrint + "'", skill, ((int) (gainedExp / time.TotalHours)).ToStringI());
                }

                // remove the timer with this name
                await Database.ExecuteNonQuery("DELETE FROM timers_exp WHERE fingerprint='" + bc.From.FingerPrint + "' AND name='" + name.Replace("'", "''") + "'");
            }
            else
            {
                if (name.Length > 0)
                {
                    await bc.SendReply("You must start timing a skill on that timer first.");
                }
                else
                {
                    await bc.SendReply("You must start timing a skill first.");
                }
            }
        }
示例#22
0
        public static async Task PcPercent(CommandContext bc)
        {
            // get rsn
            string rsn;
            if (bc.MessageTokens.Length > 1)
            {
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
            }
            else
            {
                rsn = await bc.GetPlayerName(bc.From.Nickname);
            }

            var p = await Player.FromHiscores(rsn);
            if (!p.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                return;
            }

            long expected_combat_xp = p.Skills[Skill.HITP].Exp + p.Skills[Skill.HITP].Exp * 12 / 4;
            long current_combat_xp = p.Skills[Skill.HITP].Exp + p.Skills[Skill.ATTA].Exp + p.Skills[Skill.STRE].Exp + p.Skills[Skill.DEFE].Exp + p.Skills[Skill.RANG].Exp;

            await bc.SendReply(@"\b{0}\b \c07{1:0.##}%\c of combat exp. was pest controled and/or cannoned, with \c07{2:N0}\c normal combat exp. and \c07{3:N0}\c total combat exp. (This percentage might not be accurate; magic isn't included in calculations.)", rsn, (double) (current_combat_xp - expected_combat_xp) / (double) current_combat_xp * 100.0, expected_combat_xp, current_combat_xp);
        }
示例#23
0
        public static async Task Combat(CommandContext bc)
        {
            // get @next
            var nextMatch = _nextRegex.Match(bc.Message);
            if (nextMatch.Success)
            {
                bc.Message = bc.Message.Replace(nextMatch.Value, string.Empty);
            }

            // get @experience
            var expMatch = _expRegex.Match(bc.Message);
            if (expMatch.Success)
            {
                bc.Message = bc.Message.Replace(expMatch.Value, string.Empty);
            }

            // get @rank
            var rankMatch = _rankRegex.Match(bc.Message);
            if (rankMatch.Success)
            {
                bc.Message = bc.Message.Replace(rankMatch.Value, string.Empty);
            }

            // get @virtuallevel
            var virtualMatch = _virtualRegex.Match(bc.Message);
            if (virtualMatch.Success)
            {
                bc.Message = bc.Message.Replace(virtualMatch.Value, string.Empty);
            }

            // get player
            var player = await Player.FromHiscores(await bc.GetPlayerName(bc.MessageTokens.Length == 1 ? bc.From.Nickname : bc.MessageTokens.Join(1)));
            if (!player.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", player.Name);
                return;
            }

            var playerSkills = player.Skills.Values.Where(s => s.Name != Skill.OVER && s.Name != Skill.COMB).ToList();
            var averageExp = player.Skills[Skill.OVER].Exp / playerSkills.Count;
            var avgExpThreshold = averageExp / 5;
            var highestLevelExp = playerSkills.Max(s => s.Exp);

            var expectedMaxSlayerExp = (int) ((player.Skills[Skill.HITP].Exp - 1154) * 3 / 4.0);

            var combatClass = Utils.CombatClass(player.Skills, virtualMatch.Success);
            var combatLevel = Utils.CalculateCombat(player.Skills, virtualMatch.Success);

            var reply = new StringBuilder(512)
                .AppendFormat(@"\b{0}\b \c07combat\c | level: \c07{1}\c | exp: \c07{2:e}\c | combat%: \c07{3:0.##}%\c | slayer%: \c07{4:0.##}%\c | class: \c07{5}\c", player.Name, combatLevel, player.Skills[Skill.COMB], (double) player.Skills[Skill.COMB].Exp / (double) player.Skills[Skill.OVER].Exp * 100.0, (double) player.Skills[Skill.SLAY].Exp / (double) expectedMaxSlayerExp * 100.0, combatClass);

            // Add SS rank if applicable
            var ssPlayers = (await Players.FromClan("SS")).OrderBy(p => p.Skills[Skill.COMB]);
            var ssRank = ssPlayers.FindIndex(p => p.Name.EqualsI(player.Name));
            if (ssRank != -1)
            {
                reply.AppendFormat(@" (SS rank: \c07{0}\c)", ssRank + 1);
            }

            await bc.SendReply(reply);

            var format = @" {2}\c{1:00}{0:r";
            if (expMatch.Success)
            {
                format += 'e';
            }
            else if (virtualMatch.Success)
            {
                format += 'v';
            }
            else if (!rankMatch.Success)
            {
                format += 'l';
            }
            format += @"}{3}\c {0:n}{2};";

            reply = new StringBuilder(rankMatch.Success ? @"\uSkills\u:" : @"\uSkills (to level)\u:", 512);

            foreach (var s in player.Skills.Values.Where(s => s.IsCombat))
            {
                var next = 0;
                if (!rankMatch.Success)
                {
                    switch (s.Name)
                    {
                        case Skill.ATTA:
                            next = virtualMatch.Success
                                ? Utils.NextCombatAttack(player.Skills[Skill.ATTA].VLevel, player.Skills[Skill.STRE].VLevel, player.Skills[Skill.DEFE].VLevel, player.Skills[Skill.RANG].VLevel, player.Skills[Skill.MAGI].VLevel)
                                : Utils.NextCombatAttack(player.Skills[Skill.ATTA].Level, player.Skills[Skill.STRE].Level, player.Skills[Skill.DEFE].Level, player.Skills[Skill.RANG].Level, player.Skills[Skill.MAGI].Level);
                            break;
                        case Skill.STRE:
                            next = virtualMatch.Success
                                ? Utils.NextCombatStrength(player.Skills[Skill.ATTA].VLevel, player.Skills[Skill.STRE].VLevel, player.Skills[Skill.DEFE].VLevel, player.Skills[Skill.RANG].VLevel, player.Skills[Skill.MAGI].VLevel)
                                : Utils.NextCombatStrength(player.Skills[Skill.ATTA].Level, player.Skills[Skill.STRE].Level, player.Skills[Skill.DEFE].Level, player.Skills[Skill.RANG].Level, player.Skills[Skill.MAGI].Level);
                            break;
                        case Skill.DEFE:
                            next = virtualMatch.Success
                                ? Utils.NextCombatDefence(player.Skills[Skill.ATTA].VLevel, player.Skills[Skill.STRE].VLevel, player.Skills[Skill.DEFE].VLevel, player.Skills[Skill.RANG].VLevel, player.Skills[Skill.MAGI].VLevel)
                                : Utils.NextCombatDefence(player.Skills[Skill.ATTA].Level, player.Skills[Skill.STRE].Level, player.Skills[Skill.DEFE].Level, player.Skills[Skill.RANG].Level, player.Skills[Skill.MAGI].Level);
                            break;
                        case Skill.MAGI:
                            next = virtualMatch.Success
                                ? Utils.NextCombatMagic(player.Skills[Skill.ATTA].VLevel, player.Skills[Skill.STRE].VLevel, player.Skills[Skill.DEFE].VLevel, player.Skills[Skill.RANG].VLevel, player.Skills[Skill.MAGI].VLevel)
                                : Utils.NextCombatMagic(player.Skills[Skill.ATTA].Level, player.Skills[Skill.STRE].Level, player.Skills[Skill.DEFE].Level, player.Skills[Skill.RANG].Level, player.Skills[Skill.MAGI].Level);
                            break;
                        case Skill.RANG:
                            next = virtualMatch.Success
                                ? Utils.NextCombatRanged(player.Skills[Skill.ATTA].VLevel, player.Skills[Skill.STRE].VLevel, player.Skills[Skill.DEFE].VLevel, player.Skills[Skill.RANG].VLevel, player.Skills[Skill.MAGI].VLevel)
                                : Utils.NextCombatRanged(player.Skills[Skill.ATTA].Level, player.Skills[Skill.STRE].Level, player.Skills[Skill.DEFE].Level, player.Skills[Skill.RANG].Level, player.Skills[Skill.MAGI].Level);
                            break;
                    }
                }

                reply.AppendFormat(format, s, s.Exp > averageExp + avgExpThreshold ? 3 : (s.Exp < averageExp - avgExpThreshold ? 4 : 7), s.Exp == highestLevelExp ? @"\u" : string.Empty, next > 0 ? "(+" + next + ")" : string.Empty);
            }
            await bc.SendReply(reply);

            // Show player performance if applicable
            var dblastupdate = await Database.LastUpdate(player.Name);
            if (dblastupdate != null && dblastupdate.Length == 8)
            {
                DateTime lastupdate = dblastupdate.ToDateTime();
                string perf;
                reply = new StringBuilder(512);

                var p_old = await Player.FromDatabase(player.Name, lastupdate);
                if (p_old.Ranked)
                {
                    perf = _GetPerformance("Today", p_old.Skills[Skill.COMB], player.Skills[Skill.COMB]);
                    if (perf != null)
                    {
                        reply.Append(perf + " | ");
                    }
                }
                p_old = await Player.FromDatabase(player.Name, lastupdate.AddDays(-((int) lastupdate.DayOfWeek)));
                if (p_old.Ranked)
                {
                    perf = _GetPerformance("Week", p_old.Skills[Skill.COMB], player.Skills[Skill.COMB]);
                    if (perf != null)
                    {
                        reply.Append(perf + " | ");
                    }
                }
                p_old = await Player.FromDatabase(player.Name, lastupdate.AddDays(1 - lastupdate.Day));
                if (p_old.Ranked)
                {
                    perf = _GetPerformance("Month", p_old.Skills[Skill.COMB], player.Skills[Skill.COMB]);
                    if (perf != null)
                    {
                        reply.Append(perf + " | ");
                    }
                }
                p_old = await Player.FromDatabase(player.Name, lastupdate.AddDays(1 - lastupdate.DayOfYear));
                if (p_old.Ranked)
                {
                    perf = _GetPerformance("Year", p_old.Skills[Skill.COMB], player.Skills[Skill.COMB]);
                    if (perf != null)
                    {
                        reply.Append(perf + " | ");
                    }
                }
                if (reply.Length > 0)
                {
                    var r = reply.ToString();
                    await bc.SendReply(r.EndsWithI(" | ") ? r.Substring(0, r.Length - 3) : r);
                }
            }
        }
示例#24
0
        public static async Task Grats(CommandContext bc)
        {
            if (bc.MessageTokens.Length == 1)
            {
                await bc.SendReply("Syntax: !grats <skill> <level>");
                return;
            }

            // get rsn
            var rsn = await bc.GetPlayerName(bc.From.Nickname);

            string skill = null;
            int level;
            if (int.TryParse(bc.MessageTokens[1], out level))
            {
                if (bc.MessageTokens.Length > 2 && Skill.TryParse(bc.MessageTokens[2], ref skill))
                {
                    // !grats <level> <skill>
                }
                else
                {
                    // !grats <level>
                    await bc.SendReply("Syntax: !grats <skill> <level>");
                    return;
                }
            }
            else if (Skill.TryParse(bc.MessageTokens[1], ref skill))
            {
                if (bc.MessageTokens.Length > 2 && int.TryParse(bc.MessageTokens[2], out level))
                {
                    // !grats <skill> <level>
                }
                else
                {
                    // !grats <skill>
                    var p = await Player.FromHiscores(rsn);
                    if (p.Ranked)
                    {
                        level = p.Skills[skill].VLevel;
                    }
                    else
                    {
                        level = 0;
                    }
                }
            }
            else
            {
                await bc.SendReply("Syntax: !grats <skill> <level>");
                return;
            }

            if (skill == Skill.COMB)
            {
                level = Math.Min(138, level);
            }
            else if (skill != Skill.OVER)
            {
                level = Math.Min(126, level);
            }

            bc.ReplyNotice = false;
            if (level > 0)
            {
                await bc.SendReply(@":D\-< ¤.¡*°*¡.¤ Woo! Congrats on your \c07{0} level {1} {2}\c!! ¤.¡*°*¡.¤ :D/-<", skill.ToLowerInvariant(), level, rsn);
            }
            else
            {
                await bc.SendReply(@":D\-< ¤.¡*°*¡.¤ Woo! Congrats on your \c07{0} level {1}\c!! ¤.¡*°*¡.¤ :D/-<", skill.ToLowerInvariant(), rsn);
            }
        }
示例#25
0
        public static async Task PestControl(CommandContext bc)
        {
            if (bc.MessageTokens.Length == 1)
            {
                await bc.SendReply("Syntax: !pestcontrol <skill> [rsn] #<target>");
                return;
            }
            string rsn = string.Empty;
            long target = 0;
            string skill = string.Empty;
            int points = 0;
            int rank = 0;

            // get target
            Match M = Regex.Match(bc.Message, @" #(n(?:l|r)|r?\d+(?:\.\d+)?(?:m|k)?)");
            if (M.Success)
            {
                string goal = M.Groups[1].Value;
                if (goal.EqualsI("nl"))
                {
                    target = 0;
                }
                else if (goal.EqualsI("nr"))
                {
                    rank = -1;
                }
                else if (goal.StartsWithI("r"))
                {
                    int goalRank = goal.Substring(1).ToInt32();
                    if (goalRank > 0 && goalRank <= 2000000)
                    {
                        rank = goalRank;
                    }
                    else
                    {
                        rank = -1;
                    }
                }
                else
                {
                    int goalLevel = goal.ToInt32();
                    if (goalLevel > 1 && goalLevel < 127)
                    {
                        target = goalLevel.ToExp();
                    }
                    else if (goalLevel == 127)
                    {
                        target = 200000000;
                    }
                    else if (goalLevel > 127 && goalLevel <= 200000000)
                    {
                        target = goalLevel;
                    }
                    else
                    {
                        target = 0;
                    }
                }
                bc.Message = Regex.Replace(bc.Message, @" #(n(?:l|r)|r?\d+(?:\.\d+)?(?:m|k)?)", string.Empty);
            }

            // get skill and rsn
            if (Skill.TryParse(bc.MessageTokens[1], ref skill))
            {
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(2));
            }
            else if (Skill.TryParse(bc.MessageTokens[bc.MessageTokens.Length - 1], ref skill))
            {
                bc.MessageTokens[bc.MessageTokens.Length - 1] = string.Empty;
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1).Trim());
            }
            if (!string.IsNullOrEmpty(rsn))
            {
                rsn = await bc.GetPlayerName(bc.From.Nickname);
            }

            if (string.IsNullOrEmpty(skill))
            {
                await bc.SendReply("Syntax: !pestcontrol <skill> [rsn] #<target>");
                return;
            }

            // find players exp
            var p = await Player.FromHiscores(rsn);
            if (!p.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", rsn);
                return;
            }
            Skill skillInfo = p.Skills[skill];

            // if target is a rank, find rank exp
            if (rank != 0)
            {
                if (rank == -1)
                {
                    rank = skillInfo.Rank;
                }
                foreach (Skill s in new Hiscores(skill, null, rank))
                {
                    if (s.Rank == rank)
                    {
                        target = s.Exp + 1;
                        break;
                    }
                }
            }

            long curExp = skillInfo.Exp;
            int curLvl = skillInfo.Level;
            if (target == 0 || target <= curExp)
            {
                target = (skillInfo.VLevel + 1).ToExp();
            }
            if (target > 200000000)
            {
                target = 200000000;
            }

            // count points
            double N;
            if (skill == "Prayer")
            {
                N = 18.0;
            }
            else if (skill == "Ranged" || skill == "Magic")
            {
                N = 32.0;
            }
            else
            {
                N = 35.0;
            }
            long potExp = curExp;
            var reply = new int[3];
            for (int i = 0; i < 3; i++)
            {
                double bonus;
                int group;
                if (i == 0)
                {
                    bonus = 1;
                    group = 1;
                }
                else if (i == 1)
                {
                    bonus = 1.01;
                    group = 10;
                }
                else
                {
                    bonus = 1.1;
                    group = 100;
                }
                while (potExp <= target)
                {
                    var pointExp = (int) (Math.Ceiling((curLvl + 25) * (double) (curLvl - 24) / 606.0) * N * bonus * group);
                    while ((potExp.ToLevel() < curLvl + 1 || curLvl == 99) && potExp <= target)
                    {
                        potExp += pointExp;
                        points = points + group;
                    }
                    curLvl = Math.Min(curLvl + 1, 99);
                }
                reply[i] = points;
                potExp = curExp;
                curLvl = skillInfo.Level;
                points = 0;
            }
            await bc.SendReply(@"PestControl points for \c07{0:N0}\c experience: \c07{1:N0}\c single points, \c07{2:N0}\c sets of 10 (\c07{3:N0}\c points), \c07{4:N0}\c sets of 100 (\c07{5:N0}\c points).", target - curExp, reply[0], reply[1] / 10, reply[1], reply[2] / 100, reply[2]);
        }
示例#26
0
        public static async Task HighLow(CommandContext bc)
        {
            // @rank
            bool rank = false;
            if (bc.Message.Contains(" @rank") || bc.Message.Contains(" @r"))
            {
                rank = true;
                bc.Message = bc.Message.Replace(" @rank", string.Empty);
                bc.Message = bc.Message.Replace(" @r", string.Empty);
            }

            // get rsn
            string rsn;
            if (bc.MessageTokens.Length > 1)
            {
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
            }
            else
            {
                rsn = await bc.GetPlayerName(bc.From.Nickname);
            }

            var p = await Player.FromHiscores(rsn);
            if (!p.Ranked)
            {
                await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", p.Name);
                return;
            }

            List<Skill> highest,
                        lowest;
            int i;
            string reply;

            if (rank)
            {
                highest = p.Skills.HighestRanked;
                int highestRank = highest[0].Rank;
                reply = @"\b{0}\b \uhighest\u skills:".FormatWith(rsn);
                for (i = 0; i < highest.Count; i++)
                {
                    if (highest[i].Rank != highestRank)
                    {
                        break;
                    }
                    reply += @" \c07{0}\c,".FormatWith(highest[i].Name);
                }
                reply = reply.Substring(0, reply.Length - 1) + @" level \c07{0:rv}\c ranked \c07#{0:r}\c".FormatWith(highest[0]);
                reply += @" \ufollowed by\u \c07{0:N}\c level \c07{0:rv}\c ranked \c07#{0:r}\c.".FormatWith(highest[i]);
                await bc.SendReply(reply);

                lowest = p.Skills.LowestRanked;
                int lowestRank = lowest[0].Rank;
                reply = @"\b{0}\b \ulowest\u skills:".FormatWith(rsn);
                for (i = 0; i < lowest.Count; i++)
                {
                    if (lowest[i].Rank != lowestRank)
                    {
                        break;
                    }
                    reply += @" \c07{0}\c,".FormatWith(lowest[i].Name);
                }
                reply = reply.Substring(0, reply.Length - 1) + @" level \c07{0:rv}\c ranked \c07#{0:r}\c".FormatWith(lowest[0]);
                reply += @" \ufollowed by\u \c07{0:N}\c level \c07{0:rv}\c ranked \c07#{0:r}\c.".FormatWith(lowest[i]);
                await bc.SendReply(reply);
            }
            else
            {
                highest = p.Skills.Highest;
                long highestExp = highest[0].Exp;
                reply = @"\b{0}\b \uhighest\u skills:".FormatWith(rsn);
                for (i = 0; i < highest.Count; i++)
                {
                    if (highest[i].Exp != highestExp)
                    {
                        break;
                    }
                    reply += @" \c07{0}\c,".FormatWith(highest[i].Name);
                }
                reply = reply.Substring(0, reply.Length - 1) + @" level \c07{0:rv}\c with \c07{0:e}\c exp.".FormatWith(highest[0]);
                reply += @" \ufollowed by\u \c07{0:N}\c level \c07{0:rv}\c with \c07{0:e}\c exp.".FormatWith(highest[i]);
                await bc.SendReply(reply);

                lowest = p.Skills.Lowest;
                long lowestExp = lowest[0].Exp;
                reply = @"\b{0}\b \ulowest\u skills:".FormatWith(rsn);
                for (i = 0; i < lowest.Count; i++)
                {
                    if (lowest[i].Exp != lowestExp)
                    {
                        break;
                    }
                    reply += @" \c07{0}\c,".FormatWith(lowest[i].Name);
                }
                reply = reply.Substring(0, reply.Length - 1) + @" level \c07{0:rv}\c with \c07{0:e}\c exp.".FormatWith(lowest[0]);
                reply += @" \ufollowed by\u \c07{0:N}\c level \c07{0:rv}\c with \c07{0:e}\c exp.".FormatWith(lowest[i]);
                await bc.SendReply(reply);
            }
        }
示例#27
0
        public static async Task Record(CommandContext bc)
        {
            string rsn = await bc.GetPlayerName(bc.From.Nickname);
            string skill = Skill.OVER;

            if (bc.MessageTokens.Length > 1)
            {
                if (Skill.TryParse(bc.MessageTokens[1], ref skill))
                {
                    if (bc.MessageTokens.Length > 2)
                    {
                        rsn = await bc.GetPlayerName(bc.MessageTokens.Join(2));
                    }
                }
                else
                {
                    rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
                }
            }

            try
            {
                string recordPage = new WebClient().DownloadString("http://runetracker.org/track-" + rsn + "," + Skill.NameToId(skill) + ",0");

                string recordRegex = @"Exp Gain Records[^:]+:<\/b><br \/>\s+";
                recordRegex += @"Day: <i>(?:<acronym title=""([^""]+)"">|)([^<]+)(?:<\/acronym>|)<\/i><br \/>\s+";
                recordRegex += @"Week: <i>(?:<acronym title=""([^""]+)"">|)([^<]+)(?:<\/acronym>|)<\/i><br \/>\s+";
                recordRegex += @"Month: <i>(?:<acronym title=""([^""]+)"">|)([^<]+)(?:<\/acronym>|)<\/i><br \/>";

                Match M = Regex.Match(recordPage, recordRegex, RegexOptions.Singleline);
                if (M.Success)
                {
                    await bc.SendReply(@"{0}'s records in {1}: Day \c07{2}\c ({3}); Week \c07{4}\c ({5}); Month \c07{6}\c ({7}); \c12http://runetracker.org/track-{0},{8},0\c", rsn, skill, M.Groups[2], string.IsNullOrEmpty(M.Groups[1].Value) ? "N/A" : M.Groups[1].Value, M.Groups[4], string.IsNullOrEmpty(M.Groups[3].Value) ? "N/A" : M.Groups[3].Value, M.Groups[6], string.IsNullOrEmpty(M.Groups[5].Value) ? "N/A" : M.Groups[5].Value, Skill.NameToId(skill));
                }
                else
                {
                    await bc.SendReply(@"rscript has no records in {0} for {1}.", skill, rsn);
                }
                return;
            }
            catch
            {
            }
            await bc.SendReply("rscript data source appears to be unreachable at the moment.");
        }
示例#28
0
        public static async Task CalcCombat(CommandContext bc)
        {
            if (bc.MessageTokens.Length == 1)
            {
                await bc.SendReply("Syntax: !CalcCombat Att Str Def Ran Mag");
                return;
            }

            int Att,
                Str = 0,
                Def = 0,
                Ran = 0,
                Mag = 0;

            int.TryParse(bc.MessageTokens[1], out Att);
            if (bc.MessageTokens.Length > 2)
            {
                int.TryParse(bc.MessageTokens[2], out Str);
            }
            if (bc.MessageTokens.Length > 3)
            {
                int.TryParse(bc.MessageTokens[3], out Def);
            }
            if (bc.MessageTokens.Length > 4)
            {
                int.TryParse(bc.MessageTokens[4], out Ran);
            }
            if (bc.MessageTokens.Length > 5)
            {
                int.TryParse(bc.MessageTokens[5], out Mag);
            }

            var p = await Player.FromHiscores(await bc.GetPlayerName(bc.From.Nickname));
            if (p.Ranked)
            {
                if (Att <= 0)
                {
                    Att = p.Skills[Skill.ATTA].VLevel;
                }
                if (Str <= 0)
                {
                    Str = p.Skills[Skill.STRE].VLevel;
                }
                if (Def <= 0)
                {
                    Def = p.Skills[Skill.DEFE].VLevel;
                }
                if (Ran <= 0)
                {
                    Ran = p.Skills[Skill.RANG].VLevel;
                }
                if (Mag <= 0)
                {
                    Mag = p.Skills[Skill.MAGI].VLevel;
                }
            }
            else
            {
                if (Att <= 0)
                {
                    Att = 1;
                }
                if (Str <= 0)
                {
                    Str = 1;
                }
                if (Def <= 0)
                {
                    Def = 1;
                }
                if (Ran <= 0)
                {
                    Ran = 1;
                }
                if (Mag <= 0)
                {
                    Mag = 1;
                }
            }

            string cmbclass = Utils.CombatClass(Att, Str, Ran, Mag);
            int cmblevel = Utils.CalculateCombat(Att, Str, Def, Ran, Mag);
            await bc.SendReply(@"Combat: \c07{0}\c | Class: \c07{1}\c | Stats: \c07{2} {3}\c {4} \c07{5} {6}\c", cmblevel, cmbclass, Att, Str, Def, Ran, Mag);

            int nextA = Utils.NextCombatAttack(Att, Str, Def, Ran, Mag);
            int nextS = Utils.NextCombatStrength(Att, Str, Def, Ran, Mag);
            int nextD = Utils.NextCombatDefence(Att, Str, Def, Ran, Mag);
            int nextR = Utils.NextCombatRanged(Att, Str, Def, Ran, Mag);
            int nextM = Utils.NextCombatMagic(Att, Str, Def, Ran, Mag);
            await bc.SendReply(@"Stats to level | Att: \c{0}\c | Str: \c{1}\c | Def: \c{2}\c | Range: \c{3}\c | Mage: \c{4}\c", (Att + nextA > 99 ? "04" : "03") + nextA, (Str + nextS > 99 ? "04" : "03") + nextS, (Def + nextD > 99 ? "04" : "03") + nextD, (Ran + nextR > 99 ? "04" : "03") + nextR, (Mag + nextM > 99 ? "04" : "03") + nextM);
        }
示例#29
0
        public static async Task Top(CommandContext bc)
        {
            string rsn;
            string skill = null,
                   activity = null;
            int rank;

            // get @level
            bool level = false;
            if (bc.Message.Contains(" @level") || bc.Message.Contains(" @lvl") || bc.Message.Contains(" @l"))
            {
                level = true;
                bc.Message = bc.Message.Replace(" @level", string.Empty);
                bc.Message = bc.Message.Replace(" @lvl", string.Empty);
                bc.Message = bc.Message.Replace(" @l", string.Empty);
            }

            // Parse command arguments
            if (bc.MessageTokens.Length == 1)
            {
                // !Top
                rank = 1;
                skill = Skill.OVER;
            }
            else if (Bot.Activity.TryParse(bc.MessageTokens[1], ref activity) || Skill.TryParse(bc.MessageTokens[1], ref skill))
            {
                // !Top Skill/Activity
                rank = 1;

                if (bc.MessageTokens.Length > 2)
                {
                    if (int.TryParse(bc.MessageTokens[2], out rank))
                    {
                        // !Top Skill/Activity Rank
                    }
                    else
                    {
                        // !Top Skill/Activity RSN
                        rsn = await bc.GetPlayerName(bc.MessageTokens.Join(2));
                        var p = await Player.FromHiscores(rsn);
                        if (p.Ranked)
                        {
                            if (skill == null)
                            {
                                rank = p.Activities[activity].Rank;
                            }
                            else
                            {
                                rank = p.Skills[skill].Rank;
                            }
                        }
                    }
                }
            }
            else if (int.TryParse(bc.MessageTokens[1], out rank))
            {
                // !Top Rank
                skill = Skill.OVER;
            }
            else
            {
                // !Top RSN
                rank = 1;
                skill = Skill.OVER;
                rsn = await bc.GetPlayerName(bc.MessageTokens.Join(1));
                var p = await Player.FromHiscores(rsn);
                if (p.Ranked)
                {
                    rank = p.Skills[skill].Rank;
                }
            }
            if (rank < 0)
            {
                rank = 1;
            }

            var hiscores = new Hiscores(skill, activity, rank);

            int startIndex = Math.Max(rank - hiscores[0].Rank - 5, 0);
            var reply = @"RS \u{0}\u rankings:".FormatWith(hiscores.Name.ToLowerInvariant());
            if (activity == null)
            {
                for (int i = startIndex; i < Math.Min(startIndex + 12, hiscores.Count); i++)
                {
                    reply += " ";
                    if (hiscores[i].Rank == rank)
                    {
                        reply += @"\b";
                    }

                    if (level)
                    {
                        reply += @"\c07#{0:r}\c {1} ({0:l})".FormatWith((Skill) hiscores[i], hiscores[i].RSN);
                    }
                    else
                    {
                        reply += @"\c07#{0:r}\c {1} ({0:e})".FormatWith((Skill) hiscores[i], hiscores[i].RSN);
                    }

                    if (hiscores[i].Rank == rank)
                    {
                        reply += @"\b";
                    }
                    reply += ";";
                }
            }
            else
            {
                for (int i = startIndex; i < Math.Min(12, hiscores.Count); i++)
                {
                    reply += " ";
                    if (hiscores[i].Rank == rank)
                    {
                        reply += @"\b";
                    }
                    reply += @"\c07#{0}\c {1} ({2})".FormatWith(hiscores[i].Rank, hiscores[i].RSN, ((Activity) hiscores[i]).Score);
                    if (hiscores[i].Rank == rank)
                    {
                        reply += @"\b";
                    }
                    reply += ";";
                }
            }
            await bc.SendReply(reply);
        }
示例#30
0
        public static async Task SkillInfo(CommandContext bc)
        {
            // get skill name
            string skillName = Skill.Parse(bc.MessageTokens[0]);

            // get goal
            string goal;
            Match M = Regex.Match(bc.Message, @"(?:#|goal=)(\d+|nl|nr|r\d+)");
            if (M.Success)
            {
                goal = M.Groups[1].Value;
                bc.Message = Regex.Replace(bc.Message, @"(?:#|goal=)" + goal, string.Empty);
                bc.Message = Regex.Replace(bc.Message, @"\s+", " ").TrimEnd();
                await Database.SetStringParameter("users", "goals", "fingerprint='" + bc.From.FingerPrint + "'", skillName, goal);
            }
            else
            {
                goal = await Database.GetStringParameter("users", "goals", "fingerprint='" + bc.From.FingerPrint + "'", skillName, "nl");
            }

            // get item
            string item;
            M = Regex.Match(bc.Message, "(?:@|§)(.+)");
            if (M.Success)
            {
                item = M.Groups[1].Value;
                bc.Message = Regex.Replace(bc.Message, "(?:@|§)" + item, string.Empty);
                bc.Message = Regex.Replace(bc.Message, @"\s+", " ").TrimEnd();
                await Database.SetStringParameter("users", "items", "fingerprint='" + bc.From.FingerPrint + "'", skillName, item);
            }
            else
            {
                item = await Database.GetStringParameter("users", "items", "fingerprint='" + bc.From.FingerPrint + "'", skillName, null);
            }

            // get player
            var player = await Player.FromHiscores(await bc.GetPlayerName(bc.MessageTokens.Length > 1 ? bc.MessageTokens.Join(1) : bc.From.Nickname));
            if (player.Ranked)
            {
                Skill skill = player.Skills[skillName];

                // parse goal
                int targetLevel;
                long targetExp = 0;
                if (int.TryParse(goal, out targetLevel))
                {
                    // get level/exp
                    if (targetLevel == 127)
                    {
                        targetLevel = 126;
                        targetExp = 200000000;
                    }
                    else if (targetLevel > 127)
                    {
                        targetExp = Math.Min(200000000, targetLevel);
                        targetLevel = targetExp.ToLevel();
                    }
                    else
                    {
                        targetExp = targetLevel.ToExp();
                    }
                }
                else if (goal.StartsWithI("r"))
                {
                    // get rank
                    int goalrank;
                    if (int.TryParse(goal.Substring(1), out goalrank))
                    {
                        if (goalrank > 0 && goalrank < skill.Rank)
                        {
                            foreach (Skill h in new Hiscores(skill.Name, null, goalrank))
                            {
                                if (h.Rank == goalrank)
                                {
                                    targetExp = h.Exp;
                                    targetLevel = targetExp.ToLevel();
                                    break;
                                }
                            }
                        }
                    }
                }
                else if (goal == "nr")
                {
                    // get next rank
                    if (skill.Rank > 1)
                    {
                        foreach (Skill h in new Hiscores(skill.Name, null, skill.Rank - 1))
                        {
                            if (h.Rank == skill.Rank - 1)
                            {
                                targetExp = h.Exp;
                                break;
                            }
                        }
                    }
                    else
                    {
                        targetExp = Math.Min(200000000, skill.Exp + 1);
                    }
                    targetLevel = targetExp.ToLevel();
                }
                else
                {
                    // next level
                    if (skill.VLevel == 126)
                    {
                        targetLevel = 126;
                        targetExp = 200000000;
                    }
                    else
                    {
                        targetLevel = skill.VLevel + 1;
                        targetExp = targetLevel.ToExp();
                    }
                }
                if (targetExp < skill.Exp)
                {
                    targetLevel = skill.VLevel + 1;
                    targetExp = targetLevel.ToExp();
                }

                // calculate % done
                long expToGo = 0;
                string percentDone;
                if (skill.Name == Skill.OVER)
                {
                    long totalExp = 0,
                         maxExp = 0;
                    targetLevel = 0;
                    foreach (Skill s in player.Skills.Values.Where(s => s.Name != Skill.OVER && s.Name != Skill.COMB))
                    {
                        int maxSkillExp = s.MaxLevel.ToExp();
                        totalExp += Math.Min(maxSkillExp, s.Exp);
                        maxExp += maxSkillExp;
                        targetLevel += s.MaxLevel;
                    }
                    percentDone = Math.Round(totalExp / (double) maxExp * 100.0, 1).ToStringI();

                    item = null;
                }
                else
                {
                    expToGo = targetExp - skill.Exp;
                    percentDone = Math.Round(100 - expToGo / (double) (targetExp - skill.VLevel.ToExp()) * 100, 1).ToStringI();
                }

                string reply = @"\b{0}\b \c07{1:n}\c | level: \c07{1:v}\c | exp: \c07{1:e}\c (\c07{2}%\c of {3}) | rank: \c07{1:R}\c".FormatWith(player.Name, skill, percentDone, targetLevel);

                // Add SS rank if applicable
                var ssPlayers = (await Players.FromClan("SS")).OrderBy(p => p.Skills[skill.Name]);
                var ssRank = ssPlayers.FindIndex(p => p.Name.EqualsI(player.Name));
                if (ssRank != -1)
                {
                    reply += @" (SS rank: \c07{0}\c)".FormatWith(ssRank + 1);
                }

                // Add exp to go and items
                if (expToGo > 0)
                {
                    reply += @" | \c07{0:N0}\c exp. to go".FormatWith(expToGo);

                    int speed = int.Parse(await Database.GetStringParameter("users", "speeds", "fingerprint='" + bc.From.FingerPrint + "'", skillName, "0"), CultureInfo.InvariantCulture);
                    if (speed > 0)
                    {
                        reply += @" (\c07{0}\c)".FormatWith(TimeSpan.FromHours(expToGo / (double) speed).ToLongString());
                    }

                    if (!string.IsNullOrEmpty(item))
                    {
                        switch (item.ToUpperInvariant())
                        {
                            case "LAMP":
                            case "LAMPS":
                                reply += @" (\c07{0:N0}\c lamps)".FormatWith(Utils.LampsToExp(skill.Exp, targetExp));
                                break;
                            case "BOOK":
                            case "BOOKS":
                                reply += @" (\c07{0:N0}\c books)".FormatWith(Utils.BooksToExp(skill.Exp, targetExp));
                                break;
                            case "EFFIGY":
                            case "EFFIGIES":
                                reply += @" (\c07{0:N0}\c effigies)".FormatWith(Utils.EffigyToExp(skill, targetExp));
                                break;
                            case "SW":
                            case "SOUL":
                            case "SOULS":
                            case "SOULWAR":
                            case "SOULWARS":
                                switch (skill.Name)
                                {
                                    case Skill.ATTA:
                                    case Skill.STRE:
                                    case Skill.DEFE:
                                    case Skill.HITP:
                                    case Skill.RANG:
                                    case Skill.MAGI:
                                    case Skill.PRAY:
                                    case Skill.SLAY:
                                        reply += @" (\c07{0:N0}\c/\c07{1:N0}\c zeal)".FormatWith(Utils.SoulWarsZealToExp(skill.Name, skill.Exp, targetExp, false), Utils.SoulWarsZealToExp(skill.Name, skill.Exp, targetExp, true));
                                        break;
                                    default:
                                        reply += " (unknown item)";
                                        break;
                                }
                                break;
                            case "PC":
                            case "PEST":
                            case "PESTCONTROL":
                                switch (skill.Name)
                                {
                                    case Skill.ATTA:
                                    case Skill.STRE:
                                    case Skill.DEFE:
                                    case Skill.HITP:
                                    case Skill.RANG:
                                    case Skill.MAGI:
                                    case Skill.PRAY:
                                        reply += @" (\c07{0:N0}\c/\c07{1:N0}\c/\c07{2:N0}\c points)".FormatWith(Utils.PestControlPointsToExp(skill.Name, skill.Exp, targetExp, 1), Utils.PestControlPointsToExp(skill.Name, skill.Exp, targetExp, 10), Utils.PestControlPointsToExp(skill.Name, skill.Exp, targetExp, 100));
                                        break;
                                    default:
                                        reply += " (unknown item)";
                                        break;
                                }
                                break;
                            default:
                                string item_name;
                                int monster_hp;
                                switch (skill.Name)
                                {
                                    case Skill.ATTA:
                                    case Skill.DEFE:
                                    case Skill.STRE:
                                    case Skill.RANG:
                                        if (_GetMonster(item, out item_name, out monster_hp))
                                        {
                                            reply += @" (\c07{0}\c {1})".FormatWith(Math.Ceiling(expToGo * 10d / monster_hp / 4d), item_name);
                                        }
                                        else
                                        {
                                            reply += " (unknown monster)";
                                        }
                                        break;
                                    case Skill.HITP:
                                        if (_GetMonster(item, out item_name, out monster_hp))
                                        {
                                            reply += @" (\c07{0}\c {1})".FormatWith(Math.Ceiling(expToGo * 30d / monster_hp / 4d), item_name);
                                        }
                                        else
                                        {
                                            reply += " (unknown monster)";
                                        }
                                        break;
                                    case Skill.SLAY:
                                        if (_GetMonster(item, out item_name, out monster_hp))
                                        {
                                            reply += @" (\c07{0}\c {1})".FormatWith(Math.Ceiling(expToGo * 10d / monster_hp), item_name);
                                        }
                                        else
                                        {
                                            reply += " (unknown monster)";
                                        }
                                        break;
                                    default:
                                        try
                                        {
                                            double itemExp = item.ToInt32();
                                            reply += @" (\c07{0} \citems to go.)".FormatWith(Math.Ceiling(expToGo / itemExp));
                                            break;
                                        }
                                        catch
                                        {
                                            SkillItem itemFound = _GetItem(skill.Name, item);
                                            if (itemFound != null)
                                            {
                                                reply += @" (\c07{1}\c \c{0}{2}\c)".FormatWith(itemFound.IrcColour, Math.Ceiling(expToGo / itemFound.Exp), itemFound.Name);
                                            }
                                            else
                                            {
                                                reply += " (unknown item)";
                                            }
                                            break;
                                        }
                                }
                                break;
                        }
                    }
                }

                await bc.SendReply(reply);

                // Show player performance if applicable
                DateTime lastupdate;
                var dblastupdate = await Database.LastUpdate(player.Name);
                if (dblastupdate == null || dblastupdate.Length < 8)
                {
                    lastupdate = DateTime.UtcNow.AddHours(-DateTime.UtcNow.Hour + 6).AddMinutes(-DateTime.UtcNow.Minute).AddSeconds(-DateTime.UtcNow.Second);
                    if (DateTime.UtcNow.Hour >= 0 && DateTime.UtcNow.Hour < 6)
                    {
                        lastupdate = lastupdate.AddDays(-1);
                    }
                }
                else
                {
                    lastupdate = dblastupdate.ToDateTime();
                }

                string perf;
                reply = string.Empty;

                var p_old = await Player.FromDatabase(player.Name, lastupdate);
                if (!p_old.Ranked)
                {
                    p_old = new Player(player.Name, (int) (DateTime.UtcNow - lastupdate).TotalSeconds);
                }
                if (p_old.Ranked)
                {
                    perf = _GetPerformance("Today", p_old.Skills[skill.Name], skill);
                    if (perf != null)
                    {
                        reply += perf + " | ";
                    }
                }

                p_old = await Player.FromDatabase(player.Name, lastupdate.AddDays(-((int) lastupdate.DayOfWeek)));
                if (!p_old.Ranked)
                {
                    p_old = new Player(player.Name, (int) (DateTime.UtcNow - lastupdate.AddDays(-((int) lastupdate.DayOfWeek))).TotalSeconds);
                }
                if (p_old.Ranked)
                {
                    perf = _GetPerformance("Week", p_old.Skills[skill.Name], skill);
                    if (perf != null)
                    {
                        reply += perf + " | ";
                    }
                }

                p_old = await Player.FromDatabase(player.Name, lastupdate.AddDays(1 - lastupdate.Day));
                if (!p_old.Ranked)
                {
                    p_old = new Player(player.Name, (int) (DateTime.UtcNow - lastupdate.AddDays(1 - lastupdate.Day)).TotalSeconds);
                }
                if (p_old.Ranked)
                {
                    perf = _GetPerformance("Month", p_old.Skills[skill.Name], skill);
                    if (perf != null)
                    {
                        reply += perf + " | ";
                    }
                }

                p_old = await Player.FromDatabase(player.Name, lastupdate.AddDays(1 - lastupdate.DayOfYear));
                if (!p_old.Ranked)
                {
                    p_old = new Player(player.Name, (int) (DateTime.UtcNow - lastupdate.AddDays(1 - lastupdate.DayOfYear)).TotalSeconds);
                }
                if (p_old.Ranked)
                {
                    perf = _GetPerformance("Year", p_old.Skills[skill.Name], skill);
                    if (perf != null)
                    {
                        reply += perf + " | ";
                    }
                }

                // ***** start war *****
                var warPlayer = await Database.FetchFirst("SELECT startrank,startlevel,startexp FROM warplayers WHERE channel=@channel AND rsn=@name", new MySqlParameter("@channel", bc.Channel), new MySqlParameter("@name", player.Name));
                if (warPlayer != null && await Database.Lookup<string>("skill", "wars", "channel=@chan", new[] { new MySqlParameter("@chan", bc.Channel) }) == skill.Name)
                {
                    var oldSkill = new Skill(skill.Name, warPlayer.GetInt32(0), warPlayer.GetInt32(1), warPlayer.GetInt32(2));
                    perf = _GetPerformance("War", oldSkill, skill);
                    if (perf != null)
                    {
                        reply += perf;
                    }
                }
                // ***** end war *****

                if (reply.Length > 0)
                {
                    await bc.SendReply(reply.EndsWithI(" | ") ? reply.Substring(0, reply.Length - 3) : reply);
                }

                return;
            }
            await bc.SendReply(@"\b{0}\b doesn't feature Hiscores.", player.Name);
        }