/// <summary> /// Tries to parse an item based on the text that Path of Exile gives on a Ctrl+C action. /// There is no recurring logic here so every case has to be handled manually. /// </summary> public static Item ParseItem(string text) { Item item = null; bool isIdentified, hasQuality, isCorrupted; try { var lines = text.Split(NEWLINE_SEPERATOR, StringSplitOptions.RemoveEmptyEntries); // Every item should start with Rarity in the first line. if (!lines[0].StartsWith("Rarity: ")) { throw new Exception("Probably not an item."); } // If the item is Unidentified, the second line will be its Type instead of the Name. isIdentified = !lines.Any(x => x == StringConstants.DescriptionUnidentified); hasQuality = lines.Any(x => x.Contains(StringConstants.DescriptionQuality)); isCorrupted = lines.Any(x => x == StringConstants.DescriptionCorrupted); var rarity = lines[0].Replace(StringConstants.DescriptionRarity, string.Empty); switch (rarity) { case StringConstants.RarityUnique: item = new EquippableItem(); if (isIdentified) { item.Name = lines[1]; item.Type = lines[2]; } else { item.Type = lines[1]; } var links = GetLinkCount(lines.Where(c => c.StartsWith(StringConstants.DescriptionSockets)).FirstOrDefault()); if (links >= 5) { ((EquippableItem)item).Links = new SocketFilterOption() { Min = links, Max = links, }; } ((EquippableItem)item).Rarity = rarity; break; case StringConstants.RarityRare: item = new EquippableItem() { Name = lines[2].Replace(StringConstants.PrefixSuperior, string.Empty), Type = lines[2].Replace(StringConstants.PrefixSuperior, string.Empty), ItemLevel = GetNumberFromString(lines.Where(c => c.StartsWith(StringConstants.DescriptionItemLevel)).FirstOrDefault()), Rarity = rarity, }; var links2 = GetLinkCount(lines.Where(c => c.StartsWith(StringConstants.DescriptionSockets)).FirstOrDefault()); // better naming if (links2 >= 5) { ((EquippableItem)item).Links = new SocketFilterOption() { Min = links2, Max = links2, }; } var influence = GetInfluenceType(lines.LastOrDefault()); ((EquippableItem)item).Influence = influence; break; case StringConstants.RarityMagic: throw new Exception("Magic items not supported for now."); case StringConstants.RarityNormal: if (lines.Any(c => c.StartsWith(StringConstants.DescriptionItemLevel))) // Equippable Item { item = new EquippableItem() { Type = lines[1].Replace(StringConstants.PrefixSuperior, string.Empty), ItemLevel = GetNumberFromString(lines.Where(c => c.StartsWith(StringConstants.DescriptionItemLevel)).FirstOrDefault()), Rarity = rarity, // TODO Non-Unique Rarity }; var influence2 = GetInfluenceType(lines.LastOrDefault()); // Better naming ((EquippableItem)item).Influence = influence2; var link3 = GetLinkCount(lines.Where(c => c.StartsWith(StringConstants.DescriptionSockets)).FirstOrDefault()); // Better naming if (link3 >= 5) { ((EquippableItem)item).Links = new SocketFilterOption() { Min = link3, Max = link3, }; } } else // Fragment { item = new FragmentItem() { Type = lines[1], }; } break; case StringConstants.RarityCurrency: item = new CurrencyItem() { Name = lines[1] }; break; case StringConstants.RarityGem: item = new GemItem() { Type = lines[1], // For Gems the Type has to be set to the Gem Name insead of the name itself Level = GetNumberFromString(lines[4]), Quality = hasQuality ? GetNumberFromString(lines.Where(x => x.StartsWith(StringConstants.DescriptionQuality)).FirstOrDefault()) : "0", // Quality Line Can move for different Gems }; break; case StringConstants.RarityDivinationCard: item = new CurrencyItem() { Name = lines[1], Type = lines[1], }; break; default: throw new NotImplementedException(); } } catch (Exception e) { Logger.Log("Could not parse item. " + e.Message); return(null); } item.IsCorrupted = isCorrupted ? "true" : "false"; return(item); }
/// <summary> /// Tries to parse an item based on the text that Path of Exile gives on a Ctrl+C action. /// There is no recurring logic here so every case has to be handled manually. /// </summary> public static Item ParseItem(string text) { Item item = null; bool isIdentified, hasQuality, isCorrupted, isMap, isBlighted, hasNote; try { var lines = text.Split(NEWLINE_SEPERATOR, StringSplitOptions.RemoveEmptyEntries); // Every item should start with Rarity in the first line. if (!lines[0].StartsWith(LanguageSettings.Provider.DescriptionRarity)) { throw new Exception("Probably not an item."); } // If the item is Unidentified, the second line will be its Type instead of the Name. isIdentified = !lines.Any(x => x == LanguageSettings.Provider.DescriptionUnidentified); hasQuality = lines.Any(x => x.Contains(LanguageSettings.Provider.DescriptionQuality)); isCorrupted = lines.Any(x => x == LanguageSettings.Provider.DescriptionCorrupted); isMap = lines.Any(x => x.Contains(LanguageSettings.Provider.DescriptionMapTier)); isBlighted = lines.Any(x => x.Contains(LanguageSettings.Provider.PrefixBlighted)); hasNote = lines.LastOrDefault().Contains("Note"); var rarity = lines[0].Replace(LanguageSettings.Provider.DescriptionRarity, string.Empty); if (isMap) { item = new MapItem() { ItemQuantity = GetNumberFromString(lines.Where(c => c.StartsWith(LanguageSettings.Provider.DescriptionItemQuantity)).FirstOrDefault()), ItemRarity = GetNumberFromString(lines.Where(c => c.StartsWith(LanguageSettings.Provider.DescriptionItemRarity)).FirstOrDefault()), MonsterPackSize = GetNumberFromString(lines.Where(c => c.StartsWith(LanguageSettings.Provider.DescriptionMonsterPackSize)).FirstOrDefault()), MapTier = GetNumberFromString(lines.Where(c => c.StartsWith(LanguageSettings.Provider.DescriptionMapTier)).FirstOrDefault()), Rarity = rarity, }; if (rarity == LanguageSettings.Provider.RarityNormal) { item.Name = lines[1].Replace(LanguageSettings.Provider.PrefixSuperior, string.Empty).Trim(); item.Type = lines[1].Replace(LanguageSettings.Provider.PrefixSuperior, string.Empty).Replace(LanguageSettings.Provider.PrefixBlighted, string.Empty).Trim(); } else if (rarity == LanguageSettings.Provider.RarityMagic) // Extract only map name { item.Name = LanguageSettings.Provider.PrefixBlighted + " " + TradeClient.MapNames.Where(c => lines[1].Contains(c)).FirstOrDefault(); item.Type = TradeClient.MapNames.Where(c => lines[1].Contains(c)).FirstOrDefault(); // Search map name from statics } else if (rarity == LanguageSettings.Provider.RarityRare) { item.Name = lines[2].Trim(); item.Type = lines[2].Replace(LanguageSettings.Provider.PrefixBlighted, string.Empty).Trim(); } else if (rarity == LanguageSettings.Provider.RarityUnique) { if (!isIdentified) { item.Name = lines[1].Replace(LanguageSettings.Provider.PrefixSuperior, string.Empty).Trim(); } else { item.Name = lines[1]; } } ((MapItem)item).IsBlight = isBlighted ? "true" : "false"; } else if (rarity == LanguageSettings.Provider.RarityUnique) { item = new EquippableItem { Name = lines[1], Type = isIdentified ? lines[2] : lines[1] }; var links = GetLinkCount(lines.Where(c => c.StartsWith(LanguageSettings.Provider.DescriptionSockets)).FirstOrDefault()); if (links >= 5) { ((EquippableItem)item).Links = new SocketFilterOption() { Min = links, Max = links, }; } } else if (rarity == LanguageSettings.Provider.RarityRare) { item = new EquippableItem() { Name = lines[1], Type = lines[2], ItemLevel = GetNumberFromString(lines.Where(c => c.StartsWith(LanguageSettings.Provider.DescriptionItemLevel)).FirstOrDefault()), }; var links = GetLinkCount(lines.Where(c => c.StartsWith(LanguageSettings.Provider.DescriptionSockets)).FirstOrDefault()); if (links >= 5) { ((EquippableItem)item).Links = new SocketFilterOption() { Min = links, Max = links, }; } if (hasNote) { ((EquippableItem)item).Influence = GetInfluenceType(lines[lines.Length - 3]); } else { ((EquippableItem)item).Influence = GetInfluenceType(lines.LastOrDefault()); } } else if (rarity == LanguageSettings.Provider.RarityMagic) { throw new Exception("Magic items are not yet supported."); } else if (rarity == LanguageSettings.Provider.RarityNormal) { if (lines.Any(c => c.StartsWith(LanguageSettings.Provider.DescriptionItemLevel))) // Equippable Item { item = new EquippableItem() { Type = lines[1].Replace(LanguageSettings.Provider.PrefixSuperior, string.Empty).Trim(), Name = lines[1].Replace(LanguageSettings.Provider.PrefixSuperior, string.Empty).Trim(), ItemLevel = GetNumberFromString(lines.Where(c => c.StartsWith(LanguageSettings.Provider.DescriptionItemLevel)).FirstOrDefault()), }; if (hasNote) { ((EquippableItem)item).Influence = GetInfluenceType(lines[lines.Length - 3]); } else { ((EquippableItem)item).Influence = GetInfluenceType(lines.LastOrDefault()); } var links = GetLinkCount(lines.Where(c => c.StartsWith(LanguageSettings.Provider.DescriptionSockets)).FirstOrDefault()); if (links >= 5) { ((EquippableItem)item).Links = new SocketFilterOption() { Min = links, Max = links, }; } } else if (lines.Any(c => c.Contains(LanguageSettings.Provider.KeywordProphecy))) // Prophecy { item = new ProphecyItem() { Name = lines[1], Type = lines[1], }; } else // Fragment { item = new FragmentItem() { Name = lines[1], Type = lines[1], }; } } else if (rarity == LanguageSettings.Provider.RarityCurrency) { item = new CurrencyItem() { Name = lines[1], Type = lines[1] }; } else if (rarity == LanguageSettings.Provider.RarityGem) { item = new GemItem() { Name = lines[1], // Need adjustment for Thai Language Type = lines[1], // For Gems the Type has to be set to the Gem Name insead of the name itself Level = GetNumberFromString(lines[4]), ExperiencePercent = lines.Any(x => x.StartsWith(LanguageSettings.Provider.DescriptionExperience)) ? ParseGemExperiencePercent(lines.Where(y => y.StartsWith(LanguageSettings.Provider.DescriptionExperience)).FirstOrDefault()) : 0, // Some gems have no experience like portal or max ranks Quality = hasQuality ? GetNumberFromString(lines.Where(x => x.StartsWith(LanguageSettings.Provider.DescriptionQuality)).FirstOrDefault()) : "0", // Quality Line Can move for different Gems IsVaalVersion = isCorrupted && lines[3].Contains(LanguageSettings.Provider.KeywordVaal) // check if the gem tags contain Vaal }; // if it's the vaal version, remap to have that name instead // Unsure if this works on non arabic lettering (ru/th/kr) if ((item as GemItem).IsVaalVersion) { string vaalName = lines.Where(x => x.Contains(LanguageSettings.Provider.KeywordVaal) && x.Contains(item.Name)).FirstOrDefault(); // this should capture the vaaled name version item.Name = vaalName; item.Type = vaalName; } } else if (rarity == LanguageSettings.Provider.RarityDivinationCard) { item = new DivinationCardItem() { Name = lines[1], Type = lines[1], }; } else { throw new NotImplementedException(); } if (item != null && string.IsNullOrEmpty(item.Rarity)) { item.Rarity = string.IsNullOrEmpty(rarity) ? "unknown" : rarity; } } catch (Exception e) { Logger.Log("Could not parse item. " + e.Message); return(null); } item.IsCorrupted = isCorrupted ? "true" : "false"; return(item); }