private void ReadLogFile() { running = true; List <LogLine> currentLines = new List <LogLine>(); List <LogLine> tempLines = new List <LogLine>(); DateTime lastDate = DateTime.MinValue; bool completed = false; string currentFilePath = prevFilePath; long offset = 0; while (!stop) { try { if (File.Exists(currentFilePath)) { using (FileStream fs = new FileStream(currentFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { tempLines.Clear(); if (fs.Length > offset) { fs.Seek(offset, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(fs)) { string line; DateTime currentDate = lastDate; while (!sr.EndOfStream && (line = sr.ReadLine()) != null) { LogLine logLine = new LogLine(line); if (logLine.IsValid) { int index; if ((index = line.IndexOf("[GlobalGameStateClient].PreStart called at ")) > 0) { currentDate = DateTime.SpecifyKind(DateTime.Parse(line.Substring(index + 43, 19)), DateTimeKind.Utc); OnNewLogFileDate?.Invoke(currentDate); } if (currentDate != DateTime.MinValue) { if ((int)currentDate.TimeOfDay.TotalSeconds > (int)logLine.Time.TotalSeconds) { currentDate = currentDate.AddDays(1); } currentDate = currentDate.AddSeconds(logLine.Time.TotalSeconds - currentDate.TimeOfDay.TotalSeconds); logLine.Date = currentDate; } if (line.IndexOf(" == [CompletedEpisodeDto] ==") > 0) { StringBuilder sb = new StringBuilder(line); sb.AppendLine(); while (!sr.EndOfStream && (line = sr.ReadLine()) != null) { LogLine temp = new LogLine(line); if (temp.IsValid) { logLine.Line = sb.ToString(); currentLines.AddRange(tempLines); currentLines.Add(logLine); currentLines.Add(temp); lastDate = currentDate; offset = fs.Position; tempLines.Clear(); break; } else if (!string.IsNullOrEmpty(line)) { sb.AppendLine(line); } } } else { tempLines.Add(logLine); } } else if (logLine.Line.IndexOf("Client address: ", StringComparison.OrdinalIgnoreCase) > 0) { tempLines.Add(logLine); } } } } else if (offset > fs.Length) { offset = 0; } } } if (!completed) { completed = true; offset = 0; currentFilePath = filePath; } if (currentLines.Count > 0) { lock (lines) { lines.AddRange(currentLines); currentLines.Clear(); } } else if (tempLines.Count > 0) { RoundInfo stat = null; List <RoundInfo> round = new List <RoundInfo>(); int players = 0; bool countPlayers = false; bool currentlyInParty = false; bool findPosition = false; string currentPlayerID = string.Empty; int lastPing = 0; int gameDuration = 0; for (int i = 0; i < tempLines.Count; i++) { LogLine line = tempLines[i]; ParseLine(line, round, ref currentPlayerID, ref countPlayers, ref currentlyInParty, ref findPosition, ref players, ref stat, ref lastPing, ref gameDuration); } if (lastPing != 0) { Stats.LastServerPing = lastPing; } OnParsedLogLinesCurrent?.Invoke(round); } } catch (Exception ex) { OnError?.Invoke(ex.ToString()); } Thread.Sleep(UpdateDelay); } running = false; }
private void ReadLogFile() { running = true; List <LogLine> tempLines = new List <LogLine>(); DateTime lastDate = DateTime.MinValue; bool completed = false; string currentFilePath = prevFilePath; long offset = 0; while (!stop) { try { if (File.Exists(currentFilePath)) { using (FileStream fs = new FileStream(currentFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { tempLines.Clear(); if (fs.Length > offset) { fs.Seek(offset, SeekOrigin.Begin); LineReader sr = new LineReader(fs); string line; DateTime currentDate = lastDate; while ((line = sr.ReadLine()) != null) { LogLine logLine = new LogLine(line, sr.Position); if (logLine.IsValid) { int index; if ((index = line.IndexOf("[GlobalGameStateClient].PreStart called at ")) > 0) { currentDate = DateTime.SpecifyKind(DateTime.Parse(line.Substring(index + 43, 19)), DateTimeKind.Utc); OnNewLogFileDate?.Invoke(currentDate); } if (currentDate != DateTime.MinValue) { if (currentDate.TimeOfDay.TotalSeconds - logLine.Time.TotalSeconds > 60000) { currentDate = currentDate.AddDays(1); } currentDate = currentDate.AddSeconds(logLine.Time.TotalSeconds - currentDate.TimeOfDay.TotalSeconds); logLine.Date = currentDate; } if (line.IndexOf(" == [CompletedEpisodeDto] ==") > 0) { StringBuilder sb = new StringBuilder(line); sb.AppendLine(); while ((line = sr.ReadLine()) != null) { LogLine temp = new LogLine(line, fs.Position); if (temp.IsValid) { logLine.Line = sb.ToString(); logLine.Offset = sr.Position; tempLines.Add(logLine); tempLines.Add(temp); break; } else if (!string.IsNullOrEmpty(line)) { sb.AppendLine(line); } } } else { tempLines.Add(logLine); } } else if (logLine.Line.IndexOf("Client address: ", StringComparison.OrdinalIgnoreCase) > 0) { tempLines.Add(logLine); } } } else if (offset > fs.Length) { offset = 0; } } } if (tempLines.Count > 0) { List <RoundInfo> round = new List <RoundInfo>(); LogRound logRound = new LogRound(); List <LogLine> currentLines = new List <LogLine>(); for (int i = 0; i < tempLines.Count; i++) { LogLine line = tempLines[i]; currentLines.Add(line); if (ParseLine(line, round, logRound)) { lastDate = line.Date; offset = line.Offset; lock (lines) { lines.AddRange(currentLines); currentLines.Clear(); } } else if (line.Line.IndexOf("[StateMatchmaking] Begin matchmaking", StringComparison.OrdinalIgnoreCase) > 0 || line.Line.IndexOf("[GameStateMachine] Replacing FGClient.StateMainMenu with FGClient.StatePrivateLobby", StringComparison.OrdinalIgnoreCase) > 0) { offset = i > 0 ? tempLines[i - 1].Offset : offset; lastDate = line.Date; } } if (logRound.LastPing != 0) { Stats.LastServerPing = logRound.LastPing; } OnParsedLogLinesCurrent?.Invoke(round); } if (!completed) { completed = true; offset = 0; currentFilePath = filePath; } } catch (Exception ex) { OnError?.Invoke(ex.ToString()); } Thread.Sleep(UpdateDelay); } running = false; }