private Cards.Card LookupCard(String cardname) { // look for exact match Cards.Card match; if (cards.TryGetValue(cardname.ToLower(), out match)) { return(match); } // Otherwise search using contains Cards.Card closestMatch = null; double closestPercentMatch = 0; foreach (Cards.Card c in cards.Values) { double percentMatch = 1 - (LevenshteinDistance(cardname.ToLower(), c.Name.ToLower()) / (double)c.Name.Length); if (c.Name.ToLower().Contains(cardname.ToLower())) { percentMatch += .5; // Abuse system a bit by boosting match rate if its a substring } if (percentMatch >= .5 && percentMatch > closestPercentMatch) { closestPercentMatch = percentMatch; closestMatch = c; } } return(closestMatch); }
private async void OnPrivmsg(IrcClient sender, String source, String target, String message) { // If its to me (the bot), then respond to source. Otherwise, respond to target (channel) String responseTarget = target.Equals(Client.Nick, StringComparison.CurrentCultureIgnoreCase) ? source.Substring(source.IndexOf(":") + 1, source.IndexOf("!") - (source.IndexOf(":") + 1)) : target; if (message.ToLower().StartsWith("!debug ") && message.Length > "!debug ".Length) { Cards.Card c = LookupCard(message.Substring("!debug ".Length).ToLower()); if (c == null) { Message(responseTarget, "Card not found."); return; } Console.WriteLine("Source: {0}", c.XmlSource); Console.WriteLine(c.XmlData); // Message(e.Targets[0].Name, "See terminal for debug data."); String pasteUrl = await Cards.DebugPaster.PasteCard(c); if (pasteUrl == null) { Message(target, "Paste failed."); } else { Message(target, "Debug data posted: {0}", pasteUrl); } return; } if (message.ToLower().StartsWith("!card ") && message.Length > "!card ".Length && message.Length <= (Config.MaxCardNameLength + "!card ".Length)) { // If the lookup request is longer than Config.MaxCardNameLength (default: 30) characters, // it's probably too long to be a card. LookupCardNameFor(responseTarget, message.Substring("!card ".Length).ToLower()); } Match match = regex.Match(message); for (int i = 0; i < Config.MaxCardsPerLine && match.Success; ++i, match = match.NextMatch()) { if (match.Groups[1].Length >= Config.MaxCardNameLength) { --i; continue; } LookupCardNameFor(responseTarget, match.Groups[1].Value); } }
private void LookupCardNameFor(String source, String cardname) { Cards.Card c = LookupCard(cardname); if (c == null) { this.Message(source, "The card was not found."); } else { Message(source, c.GetFullText().Replace("<b>", "").Replace("</b>", "").Replace("<i>", "").Replace("</i>", "").Replace(" \\n", ".")); } }
public static async Task<String> PasteCard(Card c) { var httpclient = new System.Net.Http.HttpClient(); var content = new System.Net.Http.MultipartFormDataContent(); Dictionary<String, String> formData = new Dictionary<String, String>(); content.Add(new System.Net.Http.StringContent(API_KEY), "api_dev_key"); content.Add(new System.Net.Http.StringContent("paste"), "api_option"); content.Add(new System.Net.Http.StringContent(String.Format("Debug data for {0}", c.Name)), "api_paste_name"); content.Add(new System.Net.Http.StringContent(String.Format("Source: {0}\n\n{1}", c.XmlSource, c.XmlData)), "api_paste_code"); var response = await httpclient.PostAsync("http://pastebin.com/api/api_post.php", content); if (!response.IsSuccessStatusCode) return null; return await response.Content.ReadAsStringAsync(); // var request = System.Net.HttpWebRequest.Create("http://pastebin.com/api/api_post.php"); // request.Method = "POST"; }
public List<Card> GetCards() { String[] files = System.IO.Directory.GetFiles(Directory, "*.xml"); List<Card> cards = new List<Card>(files.Length); XmlDocument document = new XmlDocument(); Console.WriteLine("Parsing {0} files in {1}...", files.Length, Directory); foreach (String file in files) { try { String xmlData = Encoding.UTF8.GetString(System.IO.File.ReadAllBytes(file)); document.LoadXml(xmlData); document.Load(file); //<Entity version="2" CardID="XXX_039"> XmlNode entity = document.DocumentElement.SelectSingleNode("//Entity"); if (entity == null) { Console.Error.WriteLine("Card had no CardID: {0}", file); continue; } XmlAttribute entityCardID = entity.Attributes["CardID"]; if (entityCardID == null) { Console.Error.WriteLine("Card had no CardID: {0}", file); continue; } else if (entityCardID.Value.EndsWith("e")) { Console.WriteLine("Skipping effect card: {0}", file); continue; } else if (entityCardID.Value.StartsWith("XXX_")) { Console.WriteLine("Skipping special card type: {0}", file); continue; } else if (char.IsLetter(entityCardID.Value[entityCardID.Value.Length - 1])) { Console.WriteLine("Skipping sub-card: {0}", file); continue; } // <Tag name="CardName" enumID="185" type="String"> // Gets localized names XmlNode cardName = document.DocumentElement.SelectSingleNode("//Tag[@name=\"CardName\"]"); if (cardName == null) { Console.Error.WriteLine("Card had no CardName tag: {0}", file); continue; } Card card = new Card(entityCardID.Value); card.XmlData = xmlData; card.XmlSource = file; foreach (XmlNode aName in cardName.ChildNodes) { card.SetName(aName.Name, aName.InnerText); } XmlNode cardDescription = document.DocumentElement.SelectSingleNode("//Tag[@name=\"CardTextInHand\"]"); if (cardDescription != null) { foreach (XmlNode aDescription in cardDescription.ChildNodes) { card.SetDescription(aDescription.Name, aDescription.InnerText); } } XmlNode attack = document.DocumentElement.SelectSingleNode("//Tag[@name=\"Atk\"]"); if (attack != null) card.Attack = int.Parse(attack.Attributes["value"].Value); XmlNode health = document.DocumentElement.SelectSingleNode("//Tag[@name=\"Health\"]"); if (health != null) card.Health = int.Parse(health.Attributes["value"].Value); XmlNode cost = document.DocumentElement.SelectSingleNode("//Tag[@name=\"Cost\"]"); if (cost != null) card.Cost = int.Parse(cost.Attributes["value"].Value); XmlNode durability = document.DocumentElement.SelectSingleNode("//Tag[@name=\"Durability\"]"); if (durability != null) card.Health = int.Parse(durability.Attributes["value"].Value); XmlNode classID = document.DocumentElement.SelectSingleNode("//Tag[@name=\"Class\"]"); if (classID != null) { switch (int.Parse(classID.Attributes["value"].Value)) { case (int)Card.ClassValues.MAGE: card.Class = Card.ClassValues.MAGE; break; case (int)Card.ClassValues.SHAMAN: card.Class = Card.ClassValues.SHAMAN; break; case (int)Card.ClassValues.ROGUE: card.Class = Card.ClassValues.ROGUE; break; case (int)Card.ClassValues.PALADIN: card.Class = Card.ClassValues.PALADIN; break; case (int)Card.ClassValues.PRIEST: card.Class = Card.ClassValues.PRIEST; break; case (int)Card.ClassValues.WARRIOR: card.Class = Card.ClassValues.WARRIOR; break; case (int)Card.ClassValues.WARLOCK: card.Class = Card.ClassValues.WARLOCK; break; case (int)Card.ClassValues.DRUID: card.Class = Card.ClassValues.DRUID; break; case (int)Card.ClassValues.HUNTER: card.Class = Card.ClassValues.HUNTER; break; default: card.Class = Card.ClassValues.ALL; Console.Error.WriteLine("Unknown class: {0} Class {1}", card.Name, int.Parse(classID.Attributes["value"].Value)); break; } } else card.Class = Card.ClassValues.ALL; XmlNode rarity = document.DocumentElement.SelectSingleNode("//Tag[@name=\"Rarity\"]"); if (rarity != null) { int value = int.Parse(rarity.Attributes["value"].Value); switch (value) { case 1: card.Rarity = Card.RarityValues.COMMON; break; case 2: card.Rarity = Card.RarityValues.FREE; break; case 3: card.Rarity = Card.RarityValues.RARE; break; case 4: card.Rarity = Card.RarityValues.EPIC; break; case 5: card.Rarity = Card.RarityValues.LEGENDARY; break; default: card.Rarity = Card.RarityValues.UNKNOWN; break; } } else card.Rarity = Card.RarityValues.UNKNOWN; XmlNode type = document.DocumentElement.SelectSingleNode("//Tag[@name=\"CardType\"]"); if ( type != null) { card.Type = int.Parse(type.Attributes["value"].Value); if (card.Type == (int)Card.CardType.HERO || card.Type == (int)Card.CardType.EFFECT) // Heros? 3 included the Hero "Hogger" 0/10 -- 4 may be creatures -- 7 may be weapons (warrior) continue; } cards.Add(card); } catch (XmlException exception) { Console.Error.WriteLine("There was an XML error while reading: {0}", file); Console.Error.WriteLine(exception); } } Card hearthbot = new Card("CUSTOM_HEARTHBOT"); hearthbot.SetName("enUS", "HearthBot"); hearthbot.Cost = 1; hearthbot.Health = hearthbot.Attack = 50; hearthbot.Class = Card.ClassValues.ALL; hearthbot.SetDescription("enUS",@"<b>Battlecry:</b> Destroy all secrets and deal 100 damage to the enemy hero. To get it, go here: https://github.com/aca20031/hsbot/"); cards.Add(hearthbot); return cards; }