// inhistoryrefreshparse = means reading history in batch mode // returns null if journal line is bad or its a repeat.. It does not throw private JournalEntry ProcessLine(string line, bool inhistoryrefreshparse) { // System.Diagnostics.Debug.WriteLine("Line in '" + line + "'"); int cmdrid = TravelLogUnit.CommanderId.HasValue ? TravelLogUnit.CommanderId.Value : -2; //-1 is hidden, -2 is never shown if (line.Length == 0) { return(null); } JObject jo = JObject.Parse(line, JToken.ParseOptions.AllowTrailingCommas | JToken.ParseOptions.CheckEOL); // parse, null if failed if (jo == null) // decode failed, gently return null { System.Diagnostics.Trace.WriteLine($"{TravelLogUnit.FullName} Bad journal line: {line}"); return(null); } JournalEntry je = null; try { // use a try block in case anything in the creation goes t**s up je = JournalEntry.CreateJournalEntry(jo, true); } catch { je = null; } if (je == null) { System.Diagnostics.Trace.WriteLine($"{TravelLogUnit.FullName} Bad journal creation: {line}"); return(null); } bool toosoon = false; if (je.EventTypeID == JournalTypeEnum.Fileheader) { JournalEvents.JournalFileheader header = (JournalEvents.JournalFileheader)je; if ((header.Beta && !EliteConfigInstance.InstanceOptions.DisableBetaCommanderCheck) || EliteConfigInstance.InstanceOptions.ForceBetaOnCommander) // if beta, and not disabled, or force beta { TravelLogUnit.Type |= TravelLogUnit.BetaMarker; } if (header.Part > 1) { // if we have a last continued, and its header parts match, and it has a commander, and its not too different in time.. if (lastcontinued != null && lastcontinued.Part == header.Part && lastcontinued.CommanderId >= 0 && Math.Abs(header.EventTimeUTC.Subtract(lastcontinued.EventTimeUTC).TotalSeconds) < 5) { cmdrid = lastcontinued.CommanderId; TravelLogUnit.CommanderId = lastcontinued.CommanderId; // copy commander across. } else { // this only works if you have a history... EDD does. JournalEvents.JournalContinued contd = JournalEntry.GetLast <JournalEvents.JournalContinued>(je.EventTimeUTC.AddSeconds(1), e => e.Part == header.Part); // Carry commander over from previous log if it ends with a Continued event. if (contd != null && Math.Abs(header.EventTimeUTC.Subtract(contd.EventTimeUTC).TotalSeconds) < 5 && contd.CommanderId >= 0) { cmdrid = lastcontinued.CommanderId; TravelLogUnit.CommanderId = contd.CommanderId; } } } } else if (je.EventTypeID == JournalTypeEnum.Continued) { lastcontinued = je as JournalEvents.JournalContinued; // save.. we are getting a new file soon } else if (je.EventTypeID == JournalTypeEnum.LoadGame) { var jlg = je as JournalEvents.JournalLoadGame; string newname = jlg.LoadGameCommander; if ((TravelLogUnit.Type & TravelLogUnit.BetaMarker) == TravelLogUnit.BetaMarker) { newname = "[BETA] " + newname; } EDCommander commander = EDCommander.GetCommander(newname); if (commander == null) { // in the default condition, we have a hidden commander, and first Cmdr. Jameson. commander = EDCommander.GetListCommanders().FirstOrDefault(); if (EDCommander.NumberOfCommanders == 2 && commander != null && commander.Name == "Jameson (Default)") { commander.Name = newname; commander.EdsmName = newname; EDCommander.Update(new List <EDCommander> { commander }, false); } else { commander = EDCommander.Create(name: newname, journalpath: EDJournalUIScanner.GetDefaultJournalDir().Equals(TravelLogUnit.Path) ? "" : TravelLogUnit.Path); } } commander.FID = jlg.FID; cmdrid = commander.Nr; if (!TravelLogUnit.CommanderId.HasValue) // we do not need to write to DB the TLU at this point, since we read something the upper layers will do that { TravelLogUnit.CommanderId = cmdrid; //System.Diagnostics.Trace.WriteLine(string.Format("TLU {0} updated with commander {1} at {2}", TravelLogUnit.Path, cmdrid, TravelLogUnit.Size)); } } else if (je is ISystemStationEntry && ((ISystemStationEntry)je).IsTrainingEvent) { //System.Diagnostics.Trace.WriteLine($"{filename} Training detected:\n{line}"); return(null); } if (je is IAdditionalFiles) { if ((je as IAdditionalFiles).ReadAdditionalFiles(TravelLogUnit.Path, inhistoryrefreshparse, ref jo) == false) // if failed { return(null); } } if (je is JournalEvents.JournalShipyard) // when going into shipyard { toosoon = lastshipyard != null && lastshipyard.Yard.Equals((je as JournalEvents.JournalShipyard).Yard); lastshipyard = je as JournalEvents.JournalShipyard; } else if (je is JournalEvents.JournalStoredShips) // when going into shipyard { toosoon = laststoredships != null && CollectionStaticHelpers.Equals(laststoredships.ShipsHere, (je as JournalEvents.JournalStoredShips).ShipsHere) && CollectionStaticHelpers.Equals(laststoredships.ShipsRemote, (je as JournalEvents.JournalStoredShips).ShipsRemote); laststoredships = je as JournalEvents.JournalStoredShips; } else if (je is JournalEvents.JournalStoredModules) // when going into outfitting { toosoon = laststoredmodules != null && CollectionStaticHelpers.Equals(laststoredmodules.ModuleItems, (je as JournalEvents.JournalStoredModules).ModuleItems); laststoredmodules = je as JournalEvents.JournalStoredModules; } else if (je is JournalEvents.JournalOutfitting) // when doing into outfitting { toosoon = lastoutfitting != null && lastoutfitting.ItemList.Equals((je as JournalEvents.JournalOutfitting).ItemList); lastoutfitting = je as JournalEvents.JournalOutfitting; } else if (je is JournalEvents.JournalMarket) { toosoon = lastmarket != null && lastmarket.Equals(je as JournalEvents.JournalMarket); lastmarket = je as JournalEvents.JournalMarket; } else if (je is JournalEvents.JournalCargo) { var cargo = je as JournalEvents.JournalCargo; if (lastcargo != null) { toosoon = lastcargo.SameAs(cargo); // if exactly the same, swallow. System.Diagnostics.Debug.WriteLine("Cargo vs last " + toosoon); } lastcargo = cargo; } else if (je is JournalEvents.JournalUndocked || je is JournalEvents.JournalLoadGame) // undocked, Load Game, repeats are cleared { lastshipyard = null; laststoredmodules = null; lastoutfitting = null; laststoredmodules = null; laststoredships = null; lastcargo = null; cqc = (je is JournalEvents.JournalLoadGame) && ((JournalEvents.JournalLoadGame)je).GameMode == null; } else if (je is JournalEvents.JournalMusic) { var music = je as JournalEvents.JournalMusic; if (music.MusicTrackID == JournalEvents.EDMusicTrackEnum.CQC || music.MusicTrackID == JournalEvents.EDMusicTrackEnum.CQCMenu) { cqc = true; } } else if (je is JournalEvents.JournalNavRoute) { var route = je as JournalEvents.JournalNavRoute; if (lastnavroute != null && (route.EventTimeUTC == lastnavroute.EventTimeUTC || route.EventTimeUTC == lastnavroute.EventTimeUTC.AddSeconds(1))) { toosoon = true; } lastnavroute = route; } if (toosoon) // if seeing repeats, remove { // System.Diagnostics.Debug.WriteLine("**** Remove as dup " + je.EventTypeStr); return(null); } if (cqc) // Ignore events if in CQC { return(null); } je.SetTLUCommander(TravelLogUnit.ID, cmdrid); return(je); }
public static HistoryList LoadHistory(EDJournalUIScanner journalmonitor, Func <bool> cancelRequested, Action <int, string> reportProgress, string NetLogPath = null, bool ForceNetLogReload = false, bool ForceJournalReload = false, int CurrentCommander = Int32.MinValue, int fullhistoryloaddaylimit = 0, string essentialitems = "" ) { HistoryList hist = new HistoryList(); if (CurrentCommander >= 0) { journalmonitor.SetupWatchers(); // Parse files stop monitor.. int forcereloadoflastn = ForceJournalReload ? int.MaxValue / 2 : 0; // if forcing a reload, we indicate that by setting the reload count to a very high value, but not enough to cause int wrap journalmonitor.ParseJournalFilesOnWatchers((p, s) => reportProgress(p, s), forcereloadoflastn); if (NetLogPath != null) { string errstr = null; NetLogClass.ParseFiles(NetLogPath, out errstr, EDCommander.Current.MapColour, () => cancelRequested(), (p, s) => reportProgress(p, s), ForceNetLogReload, currentcmdrid: CurrentCommander); } } Trace.WriteLine(BaseUtils.AppTicks.TickCountLap() + " Files read "); reportProgress(-1, "Reading Database"); List <JournalEntry> jlist; // returned in date ascending, oldest first order. System.Diagnostics.Debug.WriteLine(BaseUtils.AppTicks.TickCountLapDelta("HLL", true) + "History Load"); if (fullhistoryloaddaylimit > 0) { var list = (essentialitems == nameof(JournalEssentialEvents.JumpScanEssentialEvents)) ? JournalEssentialEvents.JumpScanEssentialEvents : (essentialitems == nameof(JournalEssentialEvents.JumpEssentialEvents)) ? JournalEssentialEvents.JumpEssentialEvents : (essentialitems == nameof(JournalEssentialEvents.NoEssentialEvents)) ? JournalEssentialEvents.NoEssentialEvents : (essentialitems == nameof(JournalEssentialEvents.FullStatsEssentialEvents)) ? JournalEssentialEvents.FullStatsEssentialEvents : JournalEssentialEvents.EssentialEvents; jlist = JournalEntry.GetAll(CurrentCommander, ids: list, allidsafterutc: DateTime.UtcNow.Subtract(new TimeSpan(fullhistoryloaddaylimit, 0, 0, 0)) ); } else { jlist = JournalEntry.GetAll(CurrentCommander); } System.Diagnostics.Debug.WriteLine(BaseUtils.AppTicks.TickCountLapDelta("HLL") + "History Load END"); Trace.WriteLine(BaseUtils.AppTicks.TickCountLap() + " Database read " + jlist.Count); HistoryEntry hprev = null; JournalEntry jprev = null; reportProgress(-1, "Creating History"); Stopwatch sw = new Stopwatch(); sw.Start(); foreach (JournalEntry je in jlist) { if (MergeEntries(jprev, je)) // if we merge, don't store into HE { continue; } // Clean up "UnKnown" systems from EDSM log if (je is JournalFSDJump && ((JournalFSDJump)je).StarSystem == "UnKnown") { JournalEntry.Delete(je.Id); continue; } if (je is EliteDangerousCore.JournalEvents.JournalMusic) // remove music.. not shown.. now UI event. remove it for backwards compatibility { //System.Diagnostics.Debug.WriteLine("**** Filter out " + je.EventTypeStr + " on " + je.EventTimeLocal.ToString()); continue; } long timetoload = sw.ElapsedMilliseconds; HistoryEntry he = HistoryEntry.FromJournalEntry(je, hprev); // **** REMEMBER NEW Journal entry needs this too ***************** he.UpdateMaterialsCommodities(je, hprev?.MaterialCommodity); // update material commodities Debug.Assert(he.MaterialCommodity != null); if (CheckForRemoval(he, hprev)) // check here to see if we want to remove the entry.. can move this lower later, but at first point where we have the data { continue; } he.UpdateStats(je, hprev?.Stats, he.StationFaction); he.UpdateSystemNote(); hist.CashLedger.Process(je); // update the ledger he.Credits = hist.CashLedger.CashTotal; hist.Shipyards.Process(je); hist.Outfitting.Process(je); Tuple <ShipInformation, ModulesInStore> ret = hist.ShipInformationList.Process(je, he.WhereAmI, he.System); // the ships he.UpdateShipInformation(ret.Item1); he.UpdateShipStoredModules(ret.Item2); he.UpdateMissionList(hist.missionlistaccumulator.Process(je, he.System, he.WhereAmI)); hist.historylist.Add(he); // now add it to the history AddToVisitsScan(hist, he, null); // add to scan but don't complain if can't add. Do this AFTER add, as it uses the history list hprev = he; jprev = je; } //for (int i = hist.Count - 10; i < hist.Count; i++) System.Diagnostics.Debug.WriteLine("Hist {0} {1} {2}", hist[i].EventTimeUTC, hist[i].Indexno , hist[i].EventSummary); // now database has been updated due to initial fill, now fill in stuff which needs the user database hist.CommanderId = CurrentCommander; EDCommander.Current.FID = hist.GetCommanderFID(); // ensure FID is set.. the other place it gets changed is a read of LoadGame. if (NetLogPath != null) { reportProgress(-1, "Netlog Updating System Positions"); hist.FillInPositionsFSDJumps(); // if netlog reading, try and resolve systems.. } reportProgress(-1, "Done"); return(hist); }