} // end function protected override void Down(MigrationBuilder migrationBuilder) { try { Console.WriteLine("Deleting item and spell data. This might take a few minutes... be patient and don't exit early!"); } catch { } var allItemsAndSpells = getAllItemsAndSpells(); using (var context = new TunnelQuestContext()) { using (var transaction = context.Database.BeginTransaction()) { try { // delete items first var itemsToDelete = new List <Item>(); foreach (var fullItem in allItemsAndSpells.Items) { itemsToDelete.Add(new Item() { ItemName = fullItem.ItemName }); } context.RemoveRange(itemsToDelete); context.SaveChanges(); // delete spells second var spellsToDelete = new List <Spell>(); foreach (var fullSpell in allItemsAndSpells.Spells) { spellsToDelete.Add(new Spell() { SpellName = fullSpell.SpellName }); } context.RemoveRange(spellsToDelete); context.SaveChanges(); transaction.Commit(); } catch { transaction.Rollback(); throw; } } } try { Console.WriteLine("Finished deleting item and spell data."); } catch { } }
public ChatLogic(TunnelQuestContext _context) { if (_context == null) { throw new Exception("_context cannot be null"); } this.context = _context; }
// static constructor static ChatLogic() { // get the list of all item names IEnumerable <string> itemNames; IEnumerable <Alias> itemAliases; using (var context = new TunnelQuestContext()) { itemNames = (from item in context.Items orderby item.ItemName select item.ItemName).ToArray(); itemAliases = (from alias in context.Aliases orderby alias.AliasText select alias).ToArray(); } // build itemNamesRootNode itemNamesRootNode = new Node(); foreach (Alias alias in itemAliases) { Node currentNode = itemNamesRootNode; foreach (char letter in alias.AliasText.ToLower()) // ToLower() because we want all matching to be case-insensitive { if (!currentNode.NextChars.ContainsKey(letter)) { currentNode.NextChars[letter] = new Node(); } currentNode = currentNode.NextChars[letter]; } currentNode.ItemName = alias.ItemName; } foreach (string name in itemNames) { Node currentNode = itemNamesRootNode; foreach (char letter in name.ToLower()) // ToLower() because we want all matching to be case-insensitive { if (!currentNode.NextChars.ContainsKey(letter)) { currentNode.NextChars[letter] = new Node(); } currentNode = currentNode.NextChars[letter]; } currentNode.ItemName = name; } }
protected override void Down(MigrationBuilder migrationBuilder) { using (var context = new TunnelQuestContext()) { deleteAliases(context); deleteServers(context); deleteAuthTokens(context); deleteAuthTokenStatuses(context); deleteClasses(context); deleteRaces(context); deleteSizes(context); deleteSlots(context); deleteEffectTypes(context); deleteWeaponSkills(context); deleteDeities(context); context.SaveChanges(); } }
protected override void Up(MigrationBuilder migrationBuilder) { using (var context = new TunnelQuestContext()) { insertAliases(context); insertServers(context); insertAuthTokenStatuses(context); insertAuthTokens(context); insertClasses(context); insertRaces(context); insertSizes(context); insertSlots(context); insertEffectTypes(context); insertWeaponSkills(context); insertDeities(context); context.SaveChanges(); } }
// This is the big ugly migration that contains all the logic for parsing the scraped wiki data // in the json files and inserting the database rows for items and spells. protected override void Up(MigrationBuilder migrationBuilder) { try { Console.WriteLine("Inserting item and spell data. This might take a few minutes... be patient and don't exit early!"); } catch { } var allItemsAndSpells = getAllItemsAndSpells(); using (var context = new TunnelQuestContext()) { using (var transaction = context.Database.BeginTransaction()) { try { // insert spells first context.AddRange(allItemsAndSpells.Spells); context.SaveChanges(); // insert items second context.AddRange(allItemsAndSpells.Items); context.SaveChanges(); transaction.Commit(); } catch { transaction.Rollback(); throw; } } // end using (transaction) } // end using (context) try { Console.WriteLine("Finished inserting item and spell data."); } catch { } } // end function
private void deleteEffectTypes(TunnelQuestContext context) { context.RemoveRange(getEffectTypes()); }
private void deleteDeities(TunnelQuestContext context) { context.RemoveRange(getDeities()); }
private void insertDeities(TunnelQuestContext context) { context.AddRange(getDeities()); }
private void deleteAliases(TunnelQuestContext context) { context.RemoveRange(getAliases()); }
private void insertAuthTokenStatuses(TunnelQuestContext context) { context.AddRange(getAuthTokenStatuses()); }
// private helpers #region aliases private void insertAliases(TunnelQuestContext context) { context.AddRange(getAliases()); }
private void deleteAuthTokenStatuses(TunnelQuestContext context) { context.RemoveRange(getAuthTokenStatuses()); }
private void deleteClasses(TunnelQuestContext context) { context.RemoveRange(getClasses()); }
private void insertEffectTypes(TunnelQuestContext context) { context.AddRange(getEffectTypes()); }
private void deleteSlots(TunnelQuestContext context) { context.RemoveRange(getSlots()); }
private void insertSlots(TunnelQuestContext context) { context.AddRange(getSlots()); }
private ParseResult parseChatLine(short authTokenId, string serverCode, string logLine, DateTime timeStamp, TunnelQuestContext context) { var newLine = new ChatLine(); newLine.AuthTokenId = authTokenId; newLine.ServerCode = serverCode; newLine.SentAt = timeStamp; string[] lineWords = logLine.Split(' ', StringSplitOptions.None); try { if (lineWords.Length < 3 || lineWords[1] != "auctions,") { throw new InvalidLogLineException(logLine); } } catch (IndexOutOfRangeException) { throw new InvalidLogLineException(logLine); } newLine.PlayerName = lineWords[0]; string playerTypedText = String.Join(' ', lineWords, 2, lineWords.Length - 2).Trim('\''); var segments = parseItemNames(playerTypedText, timeStamp); // At this point, the only types of segments in Segments are TextSegments and ItemNameSegments. We want // to loop through and attempt to replace each of the generic TextSegments (which represent unrecognized text) // with more specific Segments which represent recognized data elements. for (int i = 0; i < segments.Count; i++) { var segment = segments[i]; if (segment.GetType() == typeof(TextSegment)) { if (segment.Text.Contains(ChatLogic.CHAT_TOKEN)) { // in case anybody tries to be mischevious and actually type the token string into chat segments[i] = new TextSegment("clever girl", segment.HasPrecedingSpace); } else { TextSegment parsedSegment = PriceSegment.TryParse(segments, i); if (parsedSegment == null) { parsedSegment = SeparatorSegment.TryParse(segment); } if (parsedSegment == null) { parsedSegment = BuySellTradeSegment.TryParse(segment); } if (parsedSegment == null) { parsedSegment = OrBestOfferSegment.TryParse(segments, i); } if (parsedSegment != null) { segments[i] = parsedSegment; } } } } // Now that we've parsed all the segments we can recognize, go back through and see if we // can intuit any non-linked auctions (e.g. "WTS jboots mq 5k") for (int i = 0; i < segments.Count; i++) { if (segments[i].GetType() == typeof(TextSegment)) { // First, merge this TextSegment with any other TextSegments that come immediately after it var indexesToMerge = new List <int>(); indexesToMerge.Add(i); string mergedText = segments[i].Text; bool mergedTextHasPrecedingSpace = segments[i].HasPrecedingSpace; for (int j = i + 1; j < segments.Count; j++) { if (segments[j].GetType() == typeof(TextSegment)) { indexesToMerge.Add(j); if (segments[j].HasPrecedingSpace) { mergedText += ' '; } mergedText += segments[j].Text; } else { break; } } indexesToMerge.Reverse(); // delete indexes from back-to-front so that each deleted index doesn't shift the remaining ones into new positions foreach (int index in indexesToMerge) { segments.RemoveAt(index); } // Now that we've got a string containing the text of all the adjacent TextSegments, decide // whether it's something we should create an auction for bool createAuction; // Assume that any unrecognized text which comes *immediately* before or after after an item link is a // description of the item, and *not* something we should create an auction for. if (i > 0 && segments[i - 1] is ItemNameSegment) { createAuction = false; } else if (i < segments.Count && segments[i] is ItemNameSegment) { createAuction = false; } else if (mergedText.StartsWith("PST", StringComparison.InvariantCultureIgnoreCase)) { createAuction = false; } else { createAuction = true; } // STUB TODO - will probably end up adding more fine-tuned logic here after testing more // real world auction logs if (createAuction) { segments.Insert(i, new ItemNameSegment(mergedText, mergedText.Trim(), false, mergedTextHasPrecedingSpace)); // the .Trim() is important } else { segments.Insert(i, new TextSegment(mergedText, mergedTextHasPrecedingSpace)); } } } // Now that we've created all of the ItemNameSegments, loop through all the segments one last time and // use their values to build the Auction objects. If the same item name is found more than once, only create // one single auction for the item. var auctions = new Dictionary <string, Auction>(); BuySellTradeSegment lastFoundBuySellTrade = null; var itemsSinceLastSeparator = new List <ItemNameSegment>(); for (int i = 0; i < segments.Count; i++) { var segment = segments[i]; if (segment is ItemNameSegment) { var itemNameSegment = (ItemNameSegment)segment; itemsSinceLastSeparator.Add(itemNameSegment); Auction auction; if (auctions.ContainsKey(itemNameSegment.ItemName)) { auction = auctions[itemNameSegment.ItemName]; } else { auction = new Auction() { ChatLine = newLine, ChatLineId = newLine.ChatLineId, ServerCode = newLine.ServerCode, PlayerName = newLine.PlayerName, ItemName = itemNameSegment.ItemName, AliasText = itemNameSegment.AliasText, IsKnownItem = itemNameSegment.IsKnownItem, IsPermanent = true, CreatedAt = newLine.SentAt }; newLine.Auctions.Add(auction); auctions.Add(itemNameSegment.ItemName, auction); } itemNameSegment.Auction = auction; if (lastFoundBuySellTrade != null) { if (lastFoundBuySellTrade.IsBuying != null) { auction.IsBuying = lastFoundBuySellTrade.IsBuying.Value; } if (lastFoundBuySellTrade.IsAcceptingTrades != null) { auction.IsAcceptingTrades = lastFoundBuySellTrade.IsAcceptingTrades.Value; } } } else if (segment is BuySellTradeSegment) { lastFoundBuySellTrade = ((BuySellTradeSegment)segment); } else if (segment is PriceSegment) { var priceSegment = (PriceSegment)segment; var itemSegmentIndexesWithThisPrice = new List <int>(); foreach (var itemNameSegment in itemsSinceLastSeparator) { var auction = auctions[itemNameSegment.ItemName]; if (auction.Price == null) { auction.Price = priceSegment.Price; } } } else if (segment is OrBestOfferSegment) { foreach (var itemNameSegment in itemsSinceLastSeparator) { var auction = auctions[itemNameSegment.ItemName]; if (auction.Price != null) { auction.IsOrBestOffer = true; } } } else if (segment is SeparatorSegment) { itemsSinceLastSeparator.Clear(); } } // now that all the segments have been evaluated and the Auctions contain their final values, // update any previously existing auctions as necessary var auctionLogic = new AuctionLogic(context); foreach (var auction in newLine.Auctions) { auctionLogic.UpdateReplacedAuctions(auction); } return(new ParseResult() { ChatLine = newLine, Segments = segments }); }
private void insertWeaponSkills(TunnelQuestContext context) { context.AddRange(getWeaponSkills()); }
protected override void Up(MigrationBuilder migrationBuilder) { //Console.WriteLine("STUB DID NOT INSERT ANY CHAT LINES STUB"); //return; try { Console.WriteLine("Inserting data from in-game chat logs. This will take a long time... be patient and don't exit early!"); } catch { } var context = new TunnelQuestContext(); var chatLogic = new ChatLogic(context); var authToken = context.AuthTokens.FirstOrDefault(token => token.Name == "default").Value; var assembly = typeof(InsertChatLogData).GetTypeInfo().Assembly; int i = 1; bool isDone = false; do { var allFileLines = File.ReadAllLines(AppDomain.CurrentDomain.BaseDirectory + @"Migrations\Data\EcTunnelChatLogs\eqlog_project1999_" + i.ToString() + ".txt"); try { int fileLineCount = 0; DateTime lastLoggedTime = DateTime.Now; foreach (string logLineText in allFileLines) { string chatLineText = logLineText.Substring(27); string[] chatLineWords = chatLineText.Split(' '); if (chatLineWords.Length > 2 && chatLineWords[1] == "auctions,") { string timeStampString = logLineText.Substring(1, 24); string[] timeStampParts = timeStampString.Split(' '); int month; switch (timeStampParts[1]) { case "Jan": month = 1; break; case "Feb": month = 2; break; case "Mar": month = 3; break; case "Apr": month = 4; break; case "May": month = 5; break; case "Jun": month = 6; break; case "Jul": month = 7; break; case "Aug": month = 8; break; case "Sep": month = 9; break; case "Oct": month = 10; break; case "Nov": month = 11; break; case "Dec": month = 12; break; default: throw new Exception("Unknown month '" + timeStampParts[1] + "'"); } int day = Int32.Parse(timeStampParts[2]); int year = Int32.Parse(timeStampParts[4]); string[] timeParts = timeStampParts[3].Split(':'); int hour = Int32.Parse(timeParts[0]); int minute = Int32.Parse(timeParts[1]); int second = Int32.Parse(timeParts[2]); DateTime chatLineTimestamp = new DateTime(year, month, day, hour, minute, second).AddHours(6); // +6 hours to convert the log file times from Central Standard Time to UTC var result = chatLogic.ProcessLogLine(authToken, ServerCodes.Blue, chatLineText, chatLineTimestamp); fileLineCount++; if (fileLineCount % 100 == 0) { Console.WriteLine("[" + DateTime.Now.ToString() + ", took " + (DateTime.Now - lastLoggedTime).TotalSeconds.ToString() + " seconds] " + fileLineCount.ToString()); lastLoggedTime = DateTime.Now; // create a new context every so often, or else the inserts will get slower and slower // until you're processing 1 chat line per second context.Dispose(); context = new TunnelQuestContext(); chatLogic = new ChatLogic(context); } // STUB if (fileLineCount > 5000) { Console.WriteLine("STUB ended chat log import early for debugging purposes STUB"); isDone = true; break; } // END STUB } } i++; } catch (ArgumentNullException) { isDone = true; } }while (!isDone); try { Console.WriteLine("Finished inserting data from in-game chat logs."); } catch { } } // end function Up()
private void deleteWeaponSkills(TunnelQuestContext context) { context.RemoveRange(getWeaponSkills()); }