public async void Save(RunePage page) { var old = book.Pages.Single(p => p.Id == page.Id); book.Pages.Remove(old); book.Pages.Add(page); book.Selected = page.Id; var edited = srcBook.BookPages.Single(p => p.PageId == page.Id); srcBook.BookPages.ForEach(p => p.Current = false); edited.Current = true; edited.SlotEntries.Clear(); foreach (var rune in page.Runes) { edited.SlotEntries.Add(new SlotEntry { RuneSlotId = int.Parse(rune.Key), RuneId = rune.Value }); } await this.session.SpellBookService.SaveSpellBook(srcBook); }
public async Task UploadRunes(Position pos, int championId) { if (!Config.Current.LoadRunesOnLock) { return; } LogTo.Debug($"Trying to upload rune page for champion {championId}"); LogTo.Info("Downloading from provider"); Provider provider = GetProvider(); RunePage page = await Main.LoadPageFromProvider(provider, championId); if (page == null) { var positionName = pos.ToString().ToLower(); LogTo.Debug($"Could not retrieve a valid rune page for {championId} in {positionName}"); Main.ShowNotification($"No runes for position {positionName}", $"There's not enough info to set runes for your selected champion in position {positionName}", NotificationType.Error); return; } LogTo.Debug("Downloaded from provider"); LogTo.Debug("Uploading rune page to client"); await page.UploadToClient(LoL.Perks); LogTo.Debug("Uploaded rune page to client"); Main.TrackInjection(InjectionType.Runes); }
/// <summary> /// Sets a currently selected clientside runepage to a serverside runepage. /// </summary> /// <param name="RunePage">The RunePage to set</param> /// <returns></returns> public static async Task <bool> SetCurrentRunePage(RunePage RunePage) { // First get the current rune page var currentRunePage = await GetCurrentRunePage(); if (currentRunePage == null) { return(false); } // Check if reserved --> Can't swap stock pages if (currentRunePage.Id >= 50 && currentRunePage.Id <= 54) { return(false); } // Now put the new rune page in place of currently selected one HttpResponseMessage response = await _httpClient.PutAsync( $"/lol-perks/v1/pages/{currentRunePage.Id}", RunePage.AsJson() ); response.EnsureSuccessStatusCode(); return(true); }
public async Task <bool> DeleteRunePage(RunePage page) { if (!page.IsDeletable) { return(false); } return(await _connection.Delete(Endpoints.V1_LOLPERKS_PAGES + "/" + page.Id)); }
/// <summary> /// Saves the current rune page into the Observable Collection. /// </summary> public async void SaveCurrentRunePage() { var currentRunePage = await this._runes.GetCurrentRunePageAsync(); this._runePages.Add(currentRunePage); // Make it selected while we're at it, why not. this.SelectedRunePage = currentRunePage; }
/// <summary> /// Removes a currently selected rune page. /// </summary> public void DeleteCurrentPage() { this._runePages.Remove(this._selectedRunePage); // Select the first one if applicable if (this._runePages.Count > 0) { this.SelectedRunePage = this._runePages[0]; } }
protected RunePage FillStatsIfNone(RunePage page) { if (page.RuneIDs.Length == 6) { var allStats = Riot.GetStatRuneStructureAsync().Result; page.RuneIDs = page.RuneIDs.Concat(new[] { allStats[0][0].ID, allStats[1][0].ID, allStats[2][0].ID }).ToArray(); } return(page); }
public SummonerService( ILeagueApiConfiguration config) : base(config, VersionEnum.V1Rev4, "summoner") { MasteryPage.CreateMap(AutoMapperService); RunePage.CreateMap(AutoMapperService); Models.Summoner.CreateMap(AutoMapperService); #if DEBUG AutoMapperService.AssertConfigurationIsValid(); #endif }
/// <summary> /// Initializes the runes model and gets available runepages. /// </summary> /// <param name="DialogCoordinator"></param> public RunesViewModel(IDialogCoordinator DialogCoordinator) { this._dialogCoordinator = DialogCoordinator; this._runes = new Runes(); // Load rune pages from the file (if any) if (this._runes.RunePagesExist()) { this._runePages = new ObservableCollection <RunePage>(this._runes.GetSavedRunePages()); this.SelectedRunePage = this._runePages[0]; } }
public void Initialize(bool isPrimary, RunePage runePage, string priPathSelected = "(Only for secondary pathSelector)") { this.isPrimary = isPrimary; this.runePage = runePage; if (isPrimary) { GeneratePrimaryPathSelections(); } else { GenerateSecondaryPathSelections(priPathSelected); } }
public void Initialize(string strName, RunePathSelector runePathSelector, RunePage runePage, bool isPrimary) { this.strName = strName; this.runePage = runePage; this.isPrimary = isPrimary; rpathSelector = runePathSelector; Button btn = GetComponent <Button>(); btn.onClick.RemoveAllListeners(); btn.onClick.AddListener(() => { HandleOnClick(); }); btn.GetComponentInChildren <Text>().text = strName; }
public void getpages() { http.Request.Accept = HttpContentTypes.ApplicationJson; var response = http.Get("https://wepapirunepages.azurewebsites.net/api/values"); var getpages = response.DynamicBody; foreach (var page in getpages) { RunePage ImportPageBox = new RunePage(page.PageName, page.Runestart, page.Rune1, page.Rune2, page.Rune3, page.Rune4, page.RuneSecondary, page.Rune5, page.Rune6); Pagelist.Add(ImportPageBox); Pagenamelist.Add(page.PageName); } }
private void SetPageBTN_MouseDown(object sender, MouseButtonEventArgs e) { DeletePage(); if (RunesSelectList.SelectedItem == null) { RunesSelectList.SelectedIndex = 0; } String selectedPage = RunesSelectList.SelectedItem.ToString(); RunePage runes = Pagelist.Find(r => r._pageName == selectedPage); try { int Runestart = runes._runeStart; string name = runes._pageName; int rune1 = runes._rune1; int rune2 = runes._rune2; int rune3 = runes._rune3; int rune4 = runes._rune4; int rune5 = runes._rune5; int rune6 = runes._rune6; int secondary = runes._runeSecondary; var inputLCUx = @"{""name"":""" + name + "\",\"primaryStyleId\":" + Runestart + ",\"selectedPerkIds\": [" + rune1 + "," + rune2 + "," + rune3 + "," + rune4 + "," + rune5 + "," + rune6 + "],\"subStyleId\":" + secondary + "}"; string password = token; http.Request.Accept = HttpContentTypes.ApplicationJson; http.Request.SetBasicAuthentication("riot", password); var response = http.Post("https://127.0.0.1:" + port + "/lol-perks/v1/pages", inputLCUx, HttpContentTypes.ApplicationJson); if (response.StatusCode != System.Net.HttpStatusCode.OK) { var error = response.StaticBody <Error>(); if (error.message.Equals("Max pages reached")) { System.Windows.MessageBox.Show("Max Pages Reached"); } } } catch (Exception exception) { System.Windows.MessageBox.Show(exception.Message); } }
public IList <RunePage> GetRunePages() { MySqlCommand cmd = new MySqlCommand("get_runepages", connection); cmd.CommandType = CommandType.StoredProcedure; var reader = cmd.ExecuteReader(); IList <RunePage> runepages = new List <RunePage>(); while (reader.Read()) { RunePage r = RunePage.Mapper(reader); runepages.Add(r); } return(runepages); }
public AddRuneResult AddRunePage(RunePage page) { var response = League.MakeApiRequest(HttpMethod.Post, endpointRoot + "pages", page).Result; if (response.StatusCode != HttpStatusCode.OK) { var json = response.Content.ReadAsStringAsync().Result; var error = JsonConvert.DeserializeObject <Error>(json); if (error.Message.Equals("Max pages reached")) { return(AddRuneResult.MaxPageReached); } } return(AddRuneResult.Success); }
public void Initialize(bool isShowingHeroLevelOnly, Processor processor, Hero owner) { this.isShowingHeroLevelOnly = isShowingHeroLevelOnly; heroName = owner.heroName; GenerateSpellButtons(isShowingHeroLevelOnly);//Generate buttons on the attached panel SetRuneInfo(LoadRuneInfo(heroName)); Button btn = GameObjectUtility.CustomInstantiate(openRunePageBtnPrefab, transform).GetComponent <Button>(); btn.onClick.RemoveAllListeners(); btn.onClick.AddListener(() => { OpenRunePage(); }); inventory = GameObjectUtility.CustomInstantiate(inventoryPrefab, this.transform).GetComponent <Inventory>(); inventory.Initialize(processor, owner); spellPanel = GameObjectUtility.CustomInstantiate(spellPanelPrefab, this.transform).GetComponent <SpellPanel>(); runePage = GameObjectUtility.CustomInstantiate(runePagePrefab, GameObject.Find("HomeScreen").transform).GetComponent <RunePage>(); runePage.userName = heroName; heroNameLabel.text = heroName; }
private void AddPage_Click(object sender, EventArgs e) { string Newpage = Microsoft.VisualBasic.Interaction.InputBox( "Here you can add a page, a page contains a Name and the URL of Riots RunesReforged tool", "RunesReformed", "Name of page, Riot URL"); string[] SplitRiotpage = Newpage.Split(','); RiotTranslator RT = new RiotTranslator(); int[] riotpage = RT.Translate(SplitRiotpage[1]); if (string.IsNullOrEmpty(Newpage)) { return; } string CheckDupes = Pagenamelist.Find(x => x == SplitRiotpage[1]); if (CheckDupes != null) { MessageBox.Show("Duplicate Page"); } RunePage import = new RunePage( SplitRiotpage[0], riotpage[0], riotpage[1], riotpage[2], riotpage[3], riotpage[4], riotpage[5], riotpage[6], riotpage[7]); Pagelist.Add(import); Pagenamelist.Add(SplitRiotpage[0]); StreamWriter sw = new StreamWriter(Environment.CurrentDirectory + @"\Runepages.txt", true); sw.WriteLine(SplitRiotpage[0] + "," + riotpage[0] + "," + riotpage[1] + "," + riotpage[2] + "," + riotpage[3] + "," + riotpage[4] + "," + riotpage[5] + "," + riotpage[6] + ',' + riotpage[7]); sw.Flush(); sw.Close(); comboBox1_SelectedIndexChanged(Champbox, new EventArgs()); }
private void AddPage_Click(object sender, EventArgs e) { string Newpage = Microsoft.VisualBasic.Interaction.InputBox("Here you can add a page, remember to include every rune and the name of the champion.", "RunesReformed", "Twisted Fate, 8000, 8005, 9111, 9104, 8014, 8200, 8234, 8236"); string[] newpageStrings = Newpage.Split(','); RunePage import = new RunePage( newpageStrings[0], Convert.ToInt32(newpageStrings[1]), Convert.ToInt32(newpageStrings[2]), Convert.ToInt32(newpageStrings[3]), Convert.ToInt32(newpageStrings[4]), Convert.ToInt32(newpageStrings[5]), Convert.ToInt32(newpageStrings[6]), Convert.ToInt32(newpageStrings[7]), Convert.ToInt32(newpageStrings[8])); Pagelist.Add(import); Pagenamelist.Add(newpageStrings[0]); StreamWriter sw = new StreamWriter(Environment.CurrentDirectory + @"\Runepages.txt", true); sw.WriteLine(Newpage); sw.Flush(); sw.Close(); }
public void LoadOfflinePages() { string path = Environment.CurrentDirectory + @"\Runepages.txt"; if (!File.Exists(path)) { File.CreateText(path); } else { foreach (string data in File.ReadAllLines(path)) { string[] runes = data.Split(','); RunePage import = new RunePage( runes[0], Convert.ToInt32(runes[1]), Convert.ToInt32(runes[2]), Convert.ToInt32(runes[3]), Convert.ToInt32(runes[4]), Convert.ToInt32(runes[5]), Convert.ToInt32(runes[6]), Convert.ToInt32(runes[7]), Convert.ToInt32(runes[8])); Pagelist.Add(import); Pagenamelist.Add(runes[0]); } } }
private void Runebtn_Click(object sender, EventArgs e) { if (Pagebox.SelectedItem == null) { Pagebox.SelectedIndex = 0; } String selectedPage = Pagebox.SelectedItem.ToString(); RunePage runes = Pagelist.Find(r => r._pageName == selectedPage); try { int Runestart = runes._runeStart; string name = runes._pageName; int rune1 = runes._rune1; int rune2 = runes._rune2; int rune3 = runes._rune3; int rune4 = runes._rune4; int rune5 = runes._rune5; int rune6 = runes._rune6; int secondary = runes._runeSecondary; var inputLCUx = @"{""name"":""" + name + "\",\"primaryStyleId\":" + Runestart + ",\"selectedPerkIds\": [" + rune1 + "," + rune2 + "," + rune3 + "," + rune4 + "," + rune5 + "," + rune6 + "],\"subStyleId\":" + secondary + "}"; string password = token; var riotHttp = new HttpClient(); riotHttp.Request.Accept = HttpContentTypes.ApplicationJson; riotHttp.Request.SetBasicAuthentication("riot", password); riotHttp.Post("https://127.0.0.1:" + port + "/lol-perks/v1/pages", inputLCUx, HttpContentTypes.ApplicationJson); } catch (Exception exception) { MessageBox.Show("Something somewhere went wrong, show this to the admin " + exception.Message); } }
public override async Task <RunePage> GetRunePage(int championId, Position position) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(GetRoleUrl(championId, position), soft: true)); var runeClasses = doc.DocumentNode.SelectNodes("//div[@class='runeclassicon']"); if (runeClasses.Count != 2) { throw new FormatException("More than 2 rune trees found."); } var runes = doc.DocumentNode.SelectNodes("//div[contains(@class, 'tip')]"); if (runes.Count != 6) { throw new FormatException("Couldn't find all runes."); } var page = new RunePage { ChampionID = championId, Position = position, PrimaryTree = GetRuneClass(runeClasses[0]), SecondaryTree = GetRuneClass(runeClasses[1]), RuneIDs = runes.Select(o => int.Parse(o.GetAttributeValue("data-id", "0"))).ToArray() }; page.PrimaryTree = Swap(page.PrimaryTree, 8300, 8400); page.SecondaryTree = Swap(page.SecondaryTree, 8300, 8400); return(page); int GetRuneClass(HtmlNode node) => int.Parse(Regex.Match(node.ChildNodes[0].GetAttributeValue("src", ""), @"(?<=\/)\d+(?=\.)").Value); int Swap(int v, int a, int b) => v == a ? b : v == b ? a : v; }
private void Kappa_Authed(object sender, EventArgs e) { srcBook = this.session.Me.Runes; book = new RuneBook(); foreach (var srcPage in srcBook.BookPages) { var page = new RunePage { Id = srcPage.PageId, Name = srcPage.Name }; if (srcPage.Current) { book.Selected = page.Id; } foreach (var entry in srcPage.SlotEntries) { page.Runes.Add(entry.RuneSlotId.ToString(), entry.RuneId); } book.Pages.Add(page); } }
private void OnChampSelectSessionUpdate(object sender, LeagueEvent e) { // exit if no actions (usually when leaving champ select) // or auto champ select not enabled if (!e.Data["actions"].HasValues || !autoChampSelect) { return; } WriteSafe("formdebug", e.Data.ToString()); JToken bans = e.Data["bans"]; var ourBans = bans["myTeamBans"]; var theirBans = bans["theirTeamBans"]; int localCellId = Convert.ToInt32(e.Data["localPlayerCellId"]); int roleID = 0; // empty bans array is "[]". we only want to parse bans if there are any if (ourBans.ToString().Length > 2) { ParseBans(ourBans); } if (theirBans.ToString().Length > 2) { ParseBans(theirBans); } JToken actionsTop = e.Data["actions"]; JToken myTeamTop = e.Data["myTeam"]; for (int i = 0; i < myTeamTop.Count(); i++) { var curPlayer = myTeamTop.ElementAt(i); int curCellId = Convert.ToInt32(curPlayer["cellId"]); if (localCellId == curCellId) { string role = curPlayer["assignedPosition"].ToString().ToLower(); switch (role) { case "top": // top roleID = 0; break; case "jungle": // jg roleID = 1; break; case "middle": // mid roleID = 2; break; case "bottom": // adc roleID = 3; break; case "utility": // support roleID = 4; break; default: roleID = 5; break; } } } // iterate through each action (we have to do this becaused 1 action // is generated for each player at the same time meaning the last action // is only your action if you are last pick) for (int i = actionsTop.Count() - 1; i >= 0; i--) { var curAction = actionsTop.ElementAt(i).First; int curCellId = Convert.ToInt32(curAction["actorCellId"]); int actionId = Convert.ToInt32(curAction["id"]); bool myTurn = Convert.ToBoolean(curAction["isInProgress"]); string type = curAction["type"].ToString(); // current cell belongs to us and hasn't if (curCellId == localCellId && myTurn && !HandledActionIDs.Contains(curCellId)) { HandledActionIDs.Add(curCellId); if (type == "pick") { int[] currentPrefs = GetChampionPrefsByRoleID(roleID); string[] currentRunes = GetRunesByRoleID(roleID); // automatically pick based on preferred list for (int j = 0; j < PrefPoolSize; j++) { if (currentPrefs[j] != -1 && !UnavailableChampsID.Contains(currentPrefs[j])) { // lock in based on order of prefernce string str = "{\"actorCellId\": " + curCellId + ", \"championId\":" + currentPrefs[j] + ", \"completed\": true, \"id\": " + actionId + ", \"type\": \"string\"}"; API.client.MakeApiRequest(HttpMethod.Patch, "/lol-champ-select/v1/session/actions/" + actionId, str); // select runes RuneManager runeManager = new RuneManager(API.client); var allPages = runeManager.GetRunePages(); RunePage autoPage = null; // find page named "auto" foreach (RunePage p in allPages) { if (p.Name == "auto") { autoPage = p; break; } } if (autoPage != null) // if page named "auto" is found { // delete it API.client.MakeApiRequest(HttpMethod.Delete, "/lol-perks/v1/pages/" + autoPage.Id); } // convert runes string to int array // right side is runes, left side is tree ids (-) string primaryIdstr = currentRunes[j].Split('-')[0].Split(',')[0]; int primaryId = Convert.ToInt32(primaryIdstr); string secondaryIdstr = currentRunes[j].Split('-')[0].Split(',')[1]; int secondaryId = Convert.ToInt32(secondaryIdstr); string[] splitRunes = currentRunes[j].Split('-')[1].Split(','); int[] selectedRunesArr = new int[9]; for (int k = 0; k < splitRunes.Length; k++) { selectedRunesArr[k] = Convert.ToInt32(splitRunes[k]); } RunePage newPage = new RunePage() { IsActive = true, IsCurrentPage = true, Name = "auto", PrimaryTreeId = primaryId, SelectedRunes = selectedRunesArr, SecondaryTreeId = secondaryId, }; // create new rune page with runes chosen in form API.client.MakeApiRequest(HttpMethod.Post, "/lol-perks/v1/pages/", newPage); break; } } } else if (type == "ban") { // automatically ban based on preferred list for (int j = 0; j < PreferredBans.Length; j++) { if (PreferredBans[j] != -1 && !UnavailableChampsID.Contains(PreferredBans[j])) { // lock in based on order of prefernce string str = "{\"actorCellId\": " + curCellId + ", \"championId\":" + PreferredBans[j] + ", \"completed\": true, \"id\": " + actionId + ", \"type\": \"string\"}"; API.client.MakeApiRequest(HttpMethod.Patch, "/lol-champ-select/v1/session/actions/" + actionId, str); break; } //if } //for } // else if } // if } // for } //OnChampSelectSessionUpdate
public void onCopyRunePage(RunePage oldRunepage) { var name = mView.askForName(); if (name == null) { return; } onDataChanged(); var runePage = new RunePage(oldRunepage) { RunePageName = name }; mBuildManager.addRunePage(runePage); mView.addRunePage(runePage); }
public void onRunePageChanged(RunePage value) { onDataChanged(); mBuildManager.updateRunePage(value); }
public void onDeleteRunePage(RunePage item) { onDataChanged(); mBuildManager.removeRunePage(item); }
public override Task <RunePage> GetRunePage(int championId, Position position) => RunePage.GetActivePageFromClient(LCUApp.Container.Get <ILoL>().Perks);
public void updateProperty(RunePage runePage, object control) { switch (mProp) { case Prop.Mark1: runePage.Mark1 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Mark2: runePage.Mark2 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Mark3: runePage.Mark3 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Mark4: runePage.Mark4 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Mark5: runePage.Mark5 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Mark6: runePage.Mark6 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Mark7: runePage.Mark7 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Mark8: runePage.Mark8 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Mark9: runePage.Mark9 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Seal1: runePage.Seal1 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Seal2: runePage.Seal2 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Seal3: runePage.Seal3 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Seal4: runePage.Seal4 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Seal5: runePage.Seal5 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Seal6: runePage.Seal6 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Seal7: runePage.Seal7 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Seal8: runePage.Seal8 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Seal9: runePage.Seal9 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Glyph1: runePage.Glyph1 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Glyph2: runePage.Glyph2 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Glyph3: runePage.Glyph3 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Glyph4: runePage.Glyph4 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Glyph5: runePage.Glyph5 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Glyph6: runePage.Glyph6 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Glyph7: runePage.Glyph7 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Glyph8: runePage.Glyph8 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Glyph9: runePage.Glyph9 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Quint1: runePage.Quint1 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Quint2: runePage.Quint2 = (Rune)((ComboBox)control).SelectedItem; break; case Prop.Quint3: runePage.Quint3 = (Rune)((ComboBox)control).SelectedItem; break; } }
/// <summary> /// Updates a selected page serverside to new RunePage /// </summary> /// <param name="RunePage">The RunePage to update to</param> /// <returns></returns> public async Task <bool> SetCurrentRunePageAsync(RunePage RunePage) { return(await ApiClient.SetCurrentRunePage(RunePage)); }
public async Task <bool> CreateRunePage(RunePage runePage) { return(await _connection.Post(Endpoints.V1_LOLPERKS_PAGES, JsonConvert.SerializeObject(runePage))); }
public void onRenameRunePage(RunePage data) { var name = mView.askForName(); if (name == null) { return; } onDataChanged(); mView.shouldPauseBinding = true; mView.updateRunePageName(name); mView.shouldPauseBinding = false; mBuildManager.updateRunePageName(data, name); }
void LoadRunePage(RunePage page) { runeInfoCollection.Clear(); runeValues.Clear(); runePageNameTextBlock.Text = page.name; string numberPart = "[\\+|-][\\d\\W]+"; for (int i = 1; i <= 30; i++) { int runeId = 0; foreach (RuneSlot runeSlot in page.slots) { if (runeSlot.runeSlotId == i) { runeId = runeSlot.runeId; break; } } RuneStatic rune = AppConstants.runesData.data[runeId.ToString()]; string runeDescriptionModified = ""; if (rune.sanitizedDescription.Contains('(')) { int index = rune.sanitizedDescription.IndexOf('('); runeDescriptionModified = rune.sanitizedDescription.Substring(0, index); } else { runeDescriptionModified = rune.sanitizedDescription; } string runeData = Regex.Match(runeDescriptionModified, numberPart).ToString(); string runeInfo = AppConstants.ToRegularCase(runeDescriptionModified.Substring(runeData.Length)); List <double> nonNullRuneValues = new List <double>(); //foreach (double? value in rune.stats.values) //{ // if (value != null) // { // nonNullRuneValues.Add((double)value); // } //} if (nonNullRuneValues.Count == 1) { if (!runeValues.ContainsKey(runeInfo)) { RunePageInfoListViewBinding binding = new RunePageInfoListViewBinding(runeInfo, nonNullRuneValues[0], runeData.Contains('%'), runeData.Contains('+'), runeInfo.Contains("Per Level")); runeValues.Add(runeInfo, binding); } else { runeValues[runeInfo].AddToValue(nonNullRuneValues[0]); } } else if (nonNullRuneValues.Count == 2) { if (!runeValues.ContainsKey("armor penetration")) { RunePageInfoListViewBinding binding = new RunePageInfoListViewBinding("armor penetration", nonNullRuneValues[0], runeData.Contains('%'), runeData.Contains('+'), runeInfo.Contains("Per Level")); runeValues.Add("armor penetration", binding); } else { runeValues["armor penetration"].AddToValue(nonNullRuneValues[0]); } if (!runeValues.ContainsKey("magic penetration")) { RunePageInfoListViewBinding binding = new RunePageInfoListViewBinding("magic penetration", nonNullRuneValues[1], runeData.Contains('%'), runeData.Contains('+'), runeInfo.Contains("Per Level")); runeValues.Add("magic penetration", binding); } else { runeValues["magic penetration"].AddToValue(nonNullRuneValues[1]); } } runeImages[i - 1].Source = AppConstants.SetImageSource(new Uri(AppConstants.RuneIconUrl() + rune.image.full)); ToolTip toolTip = new ToolTip(); toolTip.Content = rune.name + "\n" + rune.sanitizedDescription; ToolTipService.SetToolTip(runeImages[i - 1], toolTip); } foreach (KeyValuePair <string, RunePageInfoListViewBinding> binding in runeValues) { if (binding.Value.plus) { binding.Value.RuneValue = "+"; } if (binding.Value.isPercent) { binding.Value.value *= 100; binding.Value.RuneValue += binding.Value.value.ToString() + "%"; } else { binding.Value.RuneValue += binding.Value.value.ToString("0.###"); } if (binding.Value.perLevel) { binding.Value.RuneValue += " (" + binding.Value.value * 18 + " @ lvl 18)"; } runeInfoCollection.Add(binding.Value); } }