private async void StartChampSelect()
        {
            //Force client to popup once in champion select
            Client.FocusClient();
            //Get champions and sort alphabetically

            CanLockIn = false;
            ChampList = new List<ChampionDTO>(Client.PlayerChampions);
            ChampList.Sort(
                (x, y) =>
                    string.Compare(champions.GetChampion(x.ChampionId)
                        .displayName, champions.GetChampion(y.ChampionId).displayName, StringComparison.Ordinal));
            if (Client.LoginPacket.ClientSystemStates.freeToPlayChampionsForNewPlayersMaxLevel >=
                Client.LoginPacket.AllSummonerData.SummonerLevel.Level)
                foreach (var item in ChampList)
                {
                    if (Client.LoginPacket.ClientSystemStates.freeToPlayChampionIdList.Contains(item.ChampionId))
                        item.FreeToPlay = true;
                    else
                        item.FreeToPlay = false;
                }

            //Retrieve masteries and runes
            MyMasteries = Client.LoginPacket.AllSummonerData.MasteryBook;
            MyRunes = Client.LoginPacket.AllSummonerData.SpellBook;

            //Put masteries & runes into combo boxes
            int i = 0;
            foreach (MasteryBookPageDTO masteryPage in MyMasteries.BookPages)
            {
                string masteryPageName = masteryPage.Name;
                //Stop garbage mastery names
                if (masteryPageName.StartsWith("@@"))
                    masteryPageName = "Mastery Page " + ++i;

                MasteryComboBox.Items.Add(masteryPageName);
                if (masteryPage.Current)
                    MasteryComboBox.SelectedValue = masteryPageName;
            }
            i = 0;
            foreach (SpellBookPageDTO runePage in MyRunes.BookPages)
            {
                string runePageName = runePage.Name;
                //Stop garbage rune names
                if (runePageName.StartsWith("@@"))
                    runePageName = "Rune Page " + ++i;

                RuneComboBox.Items.Add(runePageName);
                if (runePage.Current)
                    RuneComboBox.SelectedValue = runePageName;
            }
            //Allow runes & masteries to be changed
            QuickLoad = true;

            //Signal to the server we are in champion select
            await RiotCalls.SetClientReceivedGameMessage(Client.GameID, "CHAMP_SELECT_CLIENT");
            GameDTO latestDto =
                await
                    RiotCalls.GetLatestGameTimerState(Client.GameID, Client.ChampSelectDTO.GameState,
                        Client.ChampSelectDTO.PickTurn);
            //Find the game config for timers
            configType = Client.LoginPacket.GameTypeConfigs.Find(x => x.Id == latestDto.GameTypeConfigId);
            if (configType == null) //Invalid config... abort!
            {
                QuitCurrentGame();

                var overlay = new MessageOverlay
                {
                    MessageTextBox =
                    {
                        Text = "Invalid Config ID (" + latestDto.GameTypeConfigId +
                               "). Report to Eddy5641 [https://github.com/Eddy5641/LegendaryClient/issues/new]"
                    },
                    MessageTitle = { Content = "Invalid Config" }
                };
                Client.OverlayContainer.Content = overlay.Content;
                Client.OverlayContainer.Visibility = Visibility.Visible;
            }
            else
            {
                counter = configType.MainPickTimerDuration - 5;
                //Seems to be a 5 second inconsistancy with riot and what they actually provide
                CountdownTimer = new Timer();
                CountdownTimer.Tick += CountdownTimer_Tick;
                CountdownTimer.Interval = 1000; // 1 second
                CountdownTimer.Start();

                LatestDto = latestDto;
                //Get the champions for the other team to ban & sort alpabetically
                if (latestDto.GameState.ToUpper() == "PRE_CHAMP_SELECT")
                {
                    ChampionBanInfoDTO[] champsForBan = await RiotCalls.GetChampionsForBan();
                    ChampionsForBan = new List<ChampionBanInfoDTO>(champsForBan);
                    ChampionsForBan.Sort(
                        (x, y) =>
                            string.Compare(champions.GetChampion(x.ChampionId)
                                .displayName, champions.GetChampion(y.ChampionId).displayName, StringComparison.Ordinal));
                }


                //Render our champions
                RenderChamps(false);

                //Start recieving champ select
                Select_OnMessageReceived(this, latestDto);
                //Client.OnFixChampSelect += ChampSelect_OnMessageReceived;
                Client.RiotConnection.MessageReceived += ChampSelect_OnMessageReceived;
            }
        }
        private async void MasteryComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!QuickLoad) //Make loading quicker
                return;

            bool hasChanged = false;
            int i = 0;
            var bookDto = new MasteryBookDTO
            {
                SummonerId = Client.LoginPacket.AllSummonerData.Summoner.SumId,
                BookPages = new List<MasteryBookPageDTO>()
            };
            foreach (MasteryBookPageDTO masteryPage in MyMasteries.BookPages)
            {
                string masteryPageName = masteryPage.Name;
                //Convert garbage to readable so we get the proper mastery page
                if (masteryPageName.StartsWith("@@"))
                    masteryPageName = "Mastery Page " + ++i;

                masteryPage.Current = false;
                if (masteryPageName == (string)MasteryComboBox.SelectedItem)
                {
                    masteryPage.Current = true;
                    hasChanged = true;
                    var tr = new TextRange(ChatText.Document.ContentEnd, ChatText.Document.ContentEnd)
                    {
                        Text = "Selected " + masteryPageName + " as Mastery Page" + Environment.NewLine
                    };
                    tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.White);
                    ChatText.ScrollToEnd();
                }
                bookDto.BookPages.Add(masteryPage);
            }
            if (hasChanged)
                await RiotCalls.SaveMasteryBook(bookDto);
        }
        private async void MasteryPage_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!QuickLoad) //Make loading quicker
                return;

            bool HasChanged = false;
            int i = 0;
            var bookDTO = new MasteryBookDTO();
            bookDTO.SummonerId = Client.LoginPacket.AllSummonerData.Summoner.SumId;
            bookDTO.BookPages = new List<MasteryBookPageDTO>();
            foreach (MasteryBookPageDTO MasteryPage in MyMasteries.BookPages)
            {
                string MasteryPageName = MasteryPage.Name;
                //Convert garbage to readable so we get the proper mastery page
                if (MasteryPageName.StartsWith("@@"))
                {
                    MasteryPageName = "Mastery Page " + ++i;
                }
                MasteryPage.Current = false;
                if (MasteryPageName == (string)TeamPlayer.MasteryPage.SelectedItem)
                {
                    MasteryPage.Current = true;
                    HasChanged = true;
                    var tr = new TextRange(ChatText.Document.ContentEnd, ChatText.Document.ContentEnd);
                    tr.Text = "Selected " + MasteryPageName + " as Mastery Page" + Environment.NewLine;
                    tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.White);
                }
                bookDTO.BookPages.Add(MasteryPage);
            }
            if (HasChanged)
            {
                await RiotCalls.SaveMasteryBook(bookDTO);
            }
        }
        //TeamBuilder is just a little insane. This code is very messy too. :P
        /* 
         Note by horato: This code is not messy, its ugly as f**k. If you don't want to suffer from serious brain damage and moral panic
         do not attempt to study it. But hey, it works (kind of). 
         I also suck at GUI and xaml, if you want to fix my shit then be my guest ;)
        */

        public TeamBuilderPage(bool iscreater, LobbyStatus myLobby)
        {
            InitializeComponent();

            if (iscreater == false)
                Invite.IsEnabled = false;

            CurrentLobby = myLobby;

            MyMasteries = Client.LoginPacket.AllSummonerData.MasteryBook;
            MyRunes = Client.LoginPacket.AllSummonerData.SpellBook;
            LoadStats();

            Client.InviteListView = InvitedPlayers;
            Client.RiotConnection.MessageReceived += PVPNet_OnMessageReceived;
            Client.LastPageContent = Content;
            Client.CurrentPage = this;
            Client.ReturnButton.Visibility = Visibility.Visible;
            Client.ReturnButton.Content = "Return to team builder";
            Client.GameStatus = "inTeamBuilder";
            Client.SetChatHover();
            AddPlayer();

            CallWithArgs(Guid.NewGuid().ToString(), "cap", "retrieveFeatureToggles", "{}");
            CallWithArgs(Guid.NewGuid().ToString(), "cap", "retrieveInfoV1", "{\"queueId\":61}");
        }
        /// <summary>
        /// Initializes all data required for champion select. Also retrieves latest GameDTO
        /// </summary>
        private async void StartChampSelect()
        {
            //Force client to popup once in champion select
            Client.FocusClient();
            Client.IsInGame = true;
            //Get champions and sort first by favourite, then alphabetically
            ChampList = new List<ChampionDTO>(Client.PlayerChampions);
            ChampList.Sort(delegate(ChampionDTO x, ChampionDTO y)
            {
                int IsFav = champions.GetChampion(y.ChampionId).IsFavourite.CompareTo(champions.GetChampion(x.ChampionId).IsFavourite);
                if (IsFav != 0) return IsFav;
                else return champions.GetChampion(x.ChampionId).displayName.CompareTo(champions.GetChampion(y.ChampionId).displayName);
            });

            //Retrieve masteries and runes
            MyMasteries = Client.LoginPacket.AllSummonerData.MasteryBook;
            MyRunes = Client.LoginPacket.AllSummonerData.SpellBook;

            //Put masteries & runes into combo boxes
            int i = 0;
            foreach (MasteryBookPageDTO MasteryPage in MyMasteries.BookPages)
            {
                string MasteryPageName = MasteryPage.Name;
                //Stop garbage mastery names
                if (MasteryPageName.StartsWith("@@")) 
                {
                    MasteryPageName = "Mastery Page " + ++i;
                }
                MasteryComboBox.Items.Add(MasteryPageName);
                if (MasteryPage.Current)
                    MasteryComboBox.SelectedValue = MasteryPageName;
            }
            i = 0;
            foreach (SpellBookPageDTO RunePage in MyRunes.BookPages)
            {
                string RunePageName = RunePage.Name;
                //Stop garbage rune names
                if (RunePageName.StartsWith("@@"))
                {
                    RunePageName = "Rune Page " + ++i;
                }
                RuneComboBox.Items.Add(RunePageName);
                if (RunePage.Current)
                    RuneComboBox.SelectedValue = RunePageName;
            }
            //Allow runes & masteries to be changed
            QuickLoad = true;

            //Signal to the server we are in champion select
            await RiotCalls.SetClientReceivedGameMessage(Client.GameID, "CHAMP_SELECT_CLIENT");
            //Retrieve the latest GameDTO
            GameDTO latestDTO = await RiotCalls.GetLatestGameTimerState(Client.GameID, Client.ChampSelectDTO.GameState, Client.ChampSelectDTO.PickTurn);
            //Find the game config for timers
            configType = Client.LoginPacket.GameTypeConfigs.Find(x => x.Id == latestDTO.GameTypeConfigId);
            if (configType == null) //Invalid config... abort!
            {
                Client.QuitCurrentGame();

                MessageOverlay overlay = new MessageOverlay();
                overlay.MessageTextBox.Text = "Invalid Config ID (" + latestDTO.GameTypeConfigId.ToString() + "). Report to Snowl [https://github.com/Snowl/LegendaryClient/issues/new]";
                overlay.MessageTitle.Content = "Invalid Config";
                Client.OverlayContainer.Content = overlay.Content;
                Client.OverlayContainer.Visibility = Visibility.Visible;
                return;
            }
            counter = configType.MainPickTimerDuration - 5; //Seems to be a 5 second inconsistancy with riot and what they actually provide
            CountdownTimer = new System.Windows.Forms.Timer();
            CountdownTimer.Tick += new EventHandler(CountdownTimer_Tick);
            CountdownTimer.Interval = 1000; // 1 second
            CountdownTimer.Start();

            LatestDto = latestDTO;
            //Get the champions for the other team to ban & sort alpabetically
            ChampionBanInfoDTO[] ChampsForBan = await RiotCalls.GetChampionsForBan();
            ChampionsForBan = new List<ChampionBanInfoDTO>(ChampsForBan);
            ChampionsForBan.Sort((x, y) => champions.GetChampion(x.ChampionId).displayName.CompareTo(champions.GetChampion(y.ChampionId).displayName));

            //Join champion select chatroom
            string JID = Client.GetChatroomJID(latestDTO.RoomName.Replace("@sec", ""), latestDTO.RoomPassword, false);
            Chatroom = Client.ConfManager.GetRoom(new jabber.JID(JID));
            Chatroom.Nickname = Client.LoginPacket.AllSummonerData.Summoner.Name;
            Chatroom.OnRoomMessage += Chatroom_OnRoomMessage;
            Chatroom.OnParticipantJoin += Chatroom_OnParticipantJoin;
            Chatroom.Join(latestDTO.RoomPassword);

            //Render our champions
            RenderChamps(false);

            //Start recieving champ select
            ChampSelect_OnMessageReceived(this, latestDTO);
            Client.OnFixChampSelect += ChampSelect_OnMessageReceived;
            Client.RtmpConnection.MessageReceived += ChampSelect_OnMessageReceived;
        }