public JObject CreateEDDNMessage(JournalFSDJump journal) { if (!journal.HasCoordinate) return null; JObject msg = new JObject(); msg["header"] = Header(); msg["$schemaRef"] = "http://schemas.elite-markets.net/eddn/journal/1/test"; JObject message = new JObject(); message["StarSystem"] = journal.StarSystem; message["Government"] = journal.Government; message["timestamp"] = journal.EventTimeUTC.ToString("yyyy-MM-ddTHH:mm:ssZ"); message["Faction"] = journal.Faction; message["Allegiance"] = journal.Allegiance; message["StarPos"] = new JArray(new float[] { journal.StarPos.X, journal.StarPos.Y, journal.StarPos.Z }); message["Security"] = journal.Security; message["event"] = journal.EventTypeStr; message["Economy"] = journal.Economy; msg["message"] = message; return msg; }
public static int RemoveDuplicateFSDEntries(int currentcmdrid) { // list of systems in journal, sorted by time List <JournalLocOrJump> vsSystemsEnts = JournalEntry.GetAll(currentcmdrid).OfType <JournalLocOrJump>().OrderBy(j => j.EventTimeUTC).ToList(); int count = 0; using (SQLiteConnectionUser cn = new SQLiteConnectionUser(utc: true)) { for (int ji = 1; ji < vsSystemsEnts.Count; ji++) { JournalEvents.JournalFSDJump prev = vsSystemsEnts[ji - 1] as JournalEvents.JournalFSDJump; JournalEvents.JournalFSDJump current = vsSystemsEnts[ji] as JournalEvents.JournalFSDJump; if (prev != null && current != null) { bool previssame = (prev.StarSystem.Equals(current.StarSystem, StringComparison.CurrentCultureIgnoreCase) && (!prev.HasCoordinate || !current.HasCoordinate || (prev.StarPos - current.StarPos).LengthSquared < 0.01)); if (previssame) { Delete(prev.Id, cn); count++; System.Diagnostics.Debug.WriteLine("Dup {0} {1} {2} {3}", prev.Id, current.Id, prev.StarSystem, current.StarSystem); } } } } return(count); }
protected bool ParseVisitedSystem(DateTime time, TimeSpan tzoffset, string line, out JObject jo, out JournalLocOrJump je) { jo = new JObject(); jo["timestamp"] = time.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"); jo["event"] = "FSDJump"; je = null; try { Regex pattern; /* MKW: Use regular expressions to parse the log; much more readable and robust. * Example log entry: From ED 2.1 /1.6 {19:21:15} System:"Ooscs Fraae JR-L d8-112" StarPos:(-11609.469,639.594,20141.875)ly NormalFlight string rgexpstr = "{(?<Hour>\\d+):(?<Minute>\\d+):(?<Second>\\d+)} System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly( +(?<TravelMode>\\w+))?"; new from beta3? {18:15:14} System:"Pleiades Sector HR-W d1-41" StarPos:(-83.969,-146.156,-334.219)ly Body:0 RelPos:(-1.19887e+07,-9.95573e+06,2.55124e+06)km Supercruise string rgexpstr = "{(?<Hour>\\d+):(?<Minute>\\d+):(?<Second>\\d+)} System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly Body:(?<Body>\d+) StarPos:\\((?<Pos>.*?)\\)ly( +(?<TravelMode>\\w+))?"; Pre ED 2.1/1.6 {09:36:16} System:0(Thuechea JE-O b11-0) Body:1 Pos:(-6.67432e+009,7.3151e+009,-1.19125e+010) Supercruise * Also, please note that due to E:D bugs, these entries can be at the end of a line as well, not just on a line of their own. * The RegExp below actually just finds the pattern somewhere in the line, so it caters for rubbish at the end too. */ if (line.Contains("StarPos:")) // new ED 2.1 format { //{(?<Hour>\d+):(?<Minute>\d+):(?<Second>\d+)} System:"(?<SystemName>[^"]+)" StarPos:\((?<Pos>.*?)\)ly( +(?<TravelMode>\w+))? //{(?<Hour>\d+):(?<Minute>\d+):(?<Second>\d+)} System:"(?<SystemName>[^"]+)" StarPos:\((?<Pos>.*?)\)ly( +(?<TravelMode>\w+))? //string rgexpstr = "{(?<Hour>\\d+):(?<Minute>\\d+):(?<Second>\\d+)} System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly( +(?<TravelMode>\\w+))?"; string rgexpstr; if (line.Contains("Body:")) rgexpstr = "System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly Body:(?<Body>\\d+) RelPos:\\((?<RelPos>.*?)\\)km( +(?<TravelMode>\\w+))?"; else rgexpstr = "System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly( +(?<TravelMode>\\w+))?"; pattern = new Regex(rgexpstr); Match match = pattern.Match(line); if (match != null && match.Success) { //sp.Nr = int.Parse(match.Groups["Body"].Value); jo["StarSystem"] = match.Groups["SystemName"].Value; string pos = match.Groups["Pos"].Value; try { string[] xyzpos = pos.Split(','); jo["StarPos"] = new JArray( double.Parse(xyzpos[0], CultureInfo.InvariantCulture), double.Parse(xyzpos[1], CultureInfo.InvariantCulture), double.Parse(xyzpos[2], CultureInfo.InvariantCulture) ); } catch { System.Diagnostics.Trace.WriteLine("System parse error 1:" + line); return false; } } else { System.Diagnostics.Trace.WriteLine("System parse error 1:" + line); return false; } } else { pattern = new Regex(@"System:\d+\((?<SystemName>.*?)\) Body:(?<Body>\d+) Pos:\(.*?\)( (?<TravelMode>\w+))?"); Match match = pattern.Match(line); if (match != null && match.Success) { //sp.Nr = int.Parse(match.Groups["Body"].Value); jo["StarSystem"] = match.Groups["SystemName"].Value; } else { System.Diagnostics.Trace.WriteLine("System parse error 2:" + line); return false; } } je = new JournalFSDJump(jo); return true; } catch { // MKW TODO: should we log bad lines? return false; } }
public static JournalEntry CreateJournalEntry(string text) { JournalEntry je=null; JObject jo = (JObject)JObject.Parse(text); string Eventstr = Tools.GetString(jo["event"]); if (Eventstr == null) // Should normaly not happend unless corrupt string. return null; switch (Eventstr) { case "fileheader": je = new JournalFileHeader(jo); break; case "FSDJump": je = new JournalFSDJump(jo); break; case "LoadGame": je = new JournalLoadGame(jo); break; case "Bounty": case "BuyAmmo": case "BuyDrones": case "BuyExplorationData": case "BuyTradeData": case "CapShipBond": case "ClearSavedGame": case "CockpitBreached": case "CollectCargo": case "CommitCrime": case "CommunityGoalJoin": case "CommunityGoalReward": case "DatalinkScan": case "Died": case "DockFighter": case "DockingCancelled": case "DockingDenied": case "DockingGranted": case "DockingRequested": case "DockingTimeout": case "DockSRV": case "EjectCargo": case "EngineerApply": case "EngineerCraft": case "EngineerProgress": case "EscapeInterdiction": case "FactionKillBond": case "FuelScoop": case "HeatDamage": case "HeatWarning": case "HullDamage": case "Interdicted": case "Interdiction": case "LaunchFighter": case "LaunchSRV": case "Liftoff": case "Location": case "MarketBuy": case "MarketSell": case "MaterialCollected": case "MaterialDiscarded": case "MaterialDiscovered": case "MiningRefined": case "MissionAbandoned": case "MissionAccepted": case "MissionCompleted": case "MissionFailed": case "ModuleBuy": case "ModuleSell": case "ModuleSwap": case "NewCommander": case "PayFines": case "PayLegacyFines": case "PowerplayCollect": case "PowerplayDefect": case "PowerplayDeliver": case "PowerplayFastTrack": case "PowerplayJoin": case "PowerplayLeave": case "PowerplaySalary": case "PowerplayVote": case "PowerplayVoucher": case "Progress": case "Promotion": case "Rank": case "RebootRepair": case "ReceiveText": case "RedeemVoucher": case "RefuelAll": case "RefuelPartial": case "Repair": case "RestockVehicle": case "Resurrect": case "Scan": case "Screenshot": case "SelfDestruct": case "SellDrones": case "SellExplorationData": case "SendText": case "ShieldState": case "ShipyardBuy": case "ShipyardNew": case "ShipyardSell": case "ShipyardSwap": case "ShipyardTransfer": case "SupercruiseEntry": case "SupercruiseExit": case "Synthesis": case "Touchdown": case "Undocked": case "USSDrop": case "VehicleSwitch": case "WingAdd": case "WingJoin": case "WingLeave": je = new JournalUnhandled(jo, Eventstr); break; default: je = new JournalUnknown(jo); break; } return je; }
public static void ParseFiles(string datapath, out string error, int defaultMapColour, Func<bool> cancelRequested, Action<int, string> updateProgress, bool forceReload = false, Dictionary<string, NetLogFileReader> netlogreaders = null, int currentcmdrid = -1) { error = null; if (datapath == null) { error = "Netlog directory not set!"; return; } if (!Directory.Exists(datapath)) // if logfiles directory is not found { error = "Netlog directory is not present!"; return; } if (netlogreaders == null) { netlogreaders = new Dictionary<string, NetLogFileReader>(); } if (currentcmdrid < 0) { currentcmdrid = EDDConfig.Instance.CurrentCmdrID; } // TLUs List<TravelLogUnit> tlus = TravelLogUnit.GetAll(); Dictionary<string, TravelLogUnit> netlogtravelogUnits = tlus.Where(t => t.type == 1).GroupBy(t => t.Name).Select(g => g.First()).ToDictionary(t => t.Name); Dictionary<long, string> travellogunitid2name = netlogtravelogUnits.Values.ToDictionary(t => t.id, t => t.Name); Dictionary<string, List<JournalLocOrJump>> vsc_lookup = JournalEntry.GetAll().OfType<JournalLocOrJump>().GroupBy(v => v.TLUId).Where(g => travellogunitid2name.ContainsKey(g.Key)).ToDictionary(g => travellogunitid2name[g.Key], g => g.ToList()); // list of systems in journal, sorted by time List<JournalLocOrJump> vsSystemsEnts = JournalEntry.GetAll(currentcmdrid).OfType<JournalLocOrJump>().OrderBy(j => j.EventTimeUTC).ToList(); // order by file write time so we end up on the last one written FileInfo[] allFiles = Directory.EnumerateFiles(datapath, "netLog.*.log", SearchOption.AllDirectories).Select(f => new FileInfo(f)).OrderBy(p => p.LastWriteTime).ToArray(); List<NetLogFileReader> readersToUpdate = new List<NetLogFileReader>(); for (int i = 0; i < allFiles.Length; i++) { FileInfo fi = allFiles[i]; var reader = OpenFileReader(fi, netlogtravelogUnits, vsc_lookup, netlogreaders); if (!netlogtravelogUnits.ContainsKey(reader.TravelLogUnit.Name)) { netlogtravelogUnits[reader.TravelLogUnit.Name] = reader.TravelLogUnit; reader.TravelLogUnit.Add(); } if (!netlogreaders.ContainsKey(reader.TravelLogUnit.Name)) { netlogreaders[reader.TravelLogUnit.Name] = reader; } if (forceReload) { // Force a reload of the travel log reader.TravelLogUnit.Size = 0; } if (reader.filePos != fi.Length || i == allFiles.Length - 1) // File not already in DB, or is the last one { readersToUpdate.Add(reader); } } for (int i = 0; i < readersToUpdate.Count; i++) { using (SQLiteConnectionUser cn = new SQLiteConnectionUser(utc: true)) { int ji = 0; NetLogFileReader reader = readersToUpdate[i]; updateProgress(i * 100 / readersToUpdate.Count, reader.TravelLogUnit.Name); using (DbTransaction tn = cn.BeginTransaction()) { foreach (JObject jo in reader.ReadSystems(cancelRequested, currentcmdrid)) { jo["EDDMapColor"] = defaultMapColour; JournalLocOrJump je = new JournalFSDJump(jo) { TLUId = (int)reader.TravelLogUnit.id, CommanderId = currentcmdrid, }; while (ji < vsSystemsEnts.Count && vsSystemsEnts[ji].EventTimeUTC < je.EventTimeUTC) { ji++; // move to next entry which is bigger in time or equal to ours. } JournalLocOrJump prev = (ji > 0 && (ji - 1) < vsSystemsEnts.Count) ? vsSystemsEnts[ji - 1] : null; JournalLocOrJump next = ji < vsSystemsEnts.Count ? vsSystemsEnts[ji] : null; bool previssame = (prev != null && prev.StarSystem.Equals(je.StarSystem, StringComparison.CurrentCultureIgnoreCase) && (!prev.HasCoordinate || !je.HasCoordinate || (prev.StarPos - je.StarPos).LengthSquared < 0.01)); bool nextissame = (next != null && next.StarSystem.Equals(je.StarSystem, StringComparison.CurrentCultureIgnoreCase) && (!next.HasCoordinate || !je.HasCoordinate || (next.StarPos - je.StarPos).LengthSquared < 0.01)); // System.Diagnostics.Debug.WriteLine("{0} {1} {2}", ji, vsSystemsEnts[ji].EventTimeUTC, je.EventTimeUTC); if (!(previssame || nextissame)) { je.Add(cn, tn); System.Diagnostics.Debug.WriteLine("Add {0} {1}", je.EventTimeUTC, je.EventDataString); } } tn.Commit(); reader.TravelLogUnit.Update(); } if (updateProgress != null) { updateProgress((i + 1) * 100 / readersToUpdate.Count, reader.TravelLogUnit.Name); } } } }
public static List<JournalEntry> ParseFiles(string datapath, out string error, int defaultMapColour, Func<bool> cancelRequested, Action<int, string> updateProgress, bool forceReload = false, Dictionary<string, NetLogFileReader> netlogreaders = null, int currentcmdrid = -1) { error = null; if (datapath == null) { error = "Netlog directory not set!"; return null; } if (!Directory.Exists(datapath)) // if logfiles directory is not found { error = "Netlog directory is not present!"; return null; } if (netlogreaders == null) { netlogreaders = new Dictionary<string, NetLogFileReader>(); } if (currentcmdrid < 0) { currentcmdrid = EDDConfig.Instance.CurrentCmdrID; } List<JournalLocOrJump> visitedSystems = new List<JournalLocOrJump>(); Dictionary<string, TravelLogUnit> m_travelogUnits = TravelLogUnit.GetAll().Where(t => t.type == 1).GroupBy(t => t.Name).Select(g => g.First()).ToDictionary(t => t.Name); Dictionary<long, string> travellogunitid2name = m_travelogUnits.Values.ToDictionary(t => t.id, t => t.Name); Dictionary<string, List<JournalLocOrJump>> vsc_lookup = JournalEntry.GetAll().OfType<JournalLocOrJump>().GroupBy(v => v.TLUId).Where(g => travellogunitid2name.ContainsKey(g.Key)).ToDictionary(g => travellogunitid2name[g.Key], g => g.ToList()); HashSet<long> journalids = new HashSet<long>(m_travelogUnits.Values.Select(t => t.id).ToList()); List<JournalLocOrJump> vsSystemsList = JournalEntry.GetAll(currentcmdrid).OfType<JournalLocOrJump>().Where(j => journalids.Contains(j.TLUId)).ToList(); if (vsSystemsList != null) { foreach (JournalLocOrJump vs in vsSystemsList) { if (visitedSystems.Count == 0) visitedSystems.Add(vs); else if (!visitedSystems.Last().StarSystem.Equals(vs.StarSystem, StringComparison.CurrentCultureIgnoreCase)) // Avoid duplicate if times exist in same system from different files. visitedSystems.Add(vs); } } // order by file write time so we end up on the last one written FileInfo[] allFiles = Directory.EnumerateFiles(datapath, "netLog.*.log", SearchOption.AllDirectories).Select(f => new FileInfo(f)).OrderBy(p => p.LastWriteTime).ToArray(); List<NetLogFileReader> readersToUpdate = new List<NetLogFileReader>(); for (int i = 0; i < allFiles.Length; i++) { FileInfo fi = allFiles[i]; var reader = OpenFileReader(fi, m_travelogUnits, vsc_lookup, netlogreaders); if (!m_travelogUnits.ContainsKey(reader.TravelLogUnit.Name)) { m_travelogUnits[reader.TravelLogUnit.Name] = reader.TravelLogUnit; reader.TravelLogUnit.Add(); } if (!netlogreaders.ContainsKey(reader.TravelLogUnit.Name)) { netlogreaders[reader.TravelLogUnit.Name] = reader; } if (forceReload) { // Force a reload of the travel log reader.TravelLogUnit.Size = 0; } if (reader.filePos != fi.Length || i == allFiles.Length - 1) // File not already in DB, or is the last one { readersToUpdate.Add(reader); } } using (SQLiteConnectionUserUTC cn = new SQLiteConnectionUserUTC()) { for (int i = 0; i < readersToUpdate.Count; i++) { NetLogFileReader reader = readersToUpdate[i]; updateProgress(i * 100 / readersToUpdate.Count, reader.TravelLogUnit.Name); using (DbTransaction tn = cn.BeginTransaction()) { foreach (JObject jo in reader.ReadSystems(cancelRequested, currentcmdrid)) { jo["EDDMapColor"] = defaultMapColour; JournalLocOrJump je = new JournalFSDJump(jo) { TLUId = (int)reader.TravelLogUnit.id, CommanderId = currentcmdrid, }; je.Add(cn, tn); visitedSystems.Add(je); } tn.Commit(); reader.TravelLogUnit.Update(); } if (updateProgress != null) { updateProgress((i + 1) * 100 / readersToUpdate.Count, reader.TravelLogUnit.Name); } } } return visitedSystems.ToList<JournalEntry>(); }
public JObject CreateEDDNMessage(JournalFSDJump journal) { if (!journal.HasCoordinate || journal.StarPosFromEDSM) return null; JObject msg = new JObject(); msg["header"] = Header(); msg["$schemaRef"] = GetEDDNSchemaRef(); JObject message = (JObject) JObject.Parse(journal.EventDataString); if (JSONHelper.IsNullOrEmptyT(message["FuelUsed"])) // Old ED 2.1 messages has no Fuel used fields return null; message = RemoveCommonKeys(message); message.Remove("BoostUsed"); message.Remove("JumpDist"); message.Remove("FuelUsed"); message.Remove("FuelLevel"); message.Remove("StarPosFromEDSM"); msg["message"] = message; return msg; }