edjournal/JournalFile.cs

138 lines
4.7 KiB
C#
Raw Normal View History

2021-08-25 18:24:44 +02:00
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Globalization;
namespace EDJournal {
public class JournalFile : IComparable<JournalFile>
{
public string FullPath { get; set; }
public int Part { get; set; }
public DateTime DateTime { get; set; }
public DateTime NormalisedDateTime { get; set; }
public List<Entry> entries = new List<Entry>();
2021-08-25 18:24:44 +02:00
private static Regex fileregex = new Regex("Journal\\.(\\d+)\\.(\\d+)\\.log");
private static Regex update11regex = new Regex("Journal\\.([^\\.]+)\\.(\\d+).log");
2021-08-25 18:24:44 +02:00
private static string iso8601 = "yyyyMMddTHHmmss";
2021-08-25 18:24:44 +02:00
public static bool VerifyFile(string path) {
string filename = Path.GetFileName(path);
var matches = fileregex.Matches(filename);
if (matches.Count != 0) {
return true;
}
matches = update11regex.Matches(filename);
if (matches.Count != 0) {
return true;
}
return false;
2021-08-25 18:24:44 +02:00
}
private void SetFilename(string path) {
string filename = Path.GetFileName(path);
if (!File.Exists(path) || filename == null) {
throw new JournalException(string.Format("Invalid journal file: {0}", filename));
}
var matches = fileregex.Matches(filename);
if (matches.Count == 0) {
matches = update11regex.Matches(filename);
if (matches.Count == 0) {
throw new JournalException(string.Format("invalid file format: {0}", filename));
}
}
FullPath = path;
var groups = matches[0].Groups;
string part = groups[2].ToString();
string timestamp = groups[1].ToString();
if (!timestamp.Contains("T")) {
/* pre update 11 file
*/
// The ISO is not quite correct on journal filenames, so build
// a proper ISO 8601 date time stamp out of it.
var date = new StringBuilder();
date.Append("20"); // Add the missing century in front.
date.Append(timestamp);
date.Insert(8, "T"); // Add the "T" separating date and time
timestamp = date.ToString();
} else {
/* post update 11 file, remove dashes
*/
timestamp = timestamp.Replace("-", "");
2021-08-25 18:24:44 +02:00
}
this.DateTime = DateTime.ParseExact(timestamp, iso8601, CultureInfo.InvariantCulture);
this.Part = int.Parse(part);
this.NormalisedDateTime = DateTime.Parse(DateTime.ToShortDateString());
2021-08-25 18:24:44 +02:00
}
public int CompareTo(JournalFile other) {
if (DateTime == null || other.DateTime == null) {
2021-08-25 18:24:44 +02:00
return 0;
}
var comp = DateTime.Compare(DateTime, other.DateTime);
2021-08-25 18:24:44 +02:00
if (comp == 0) {
/* If we have the exact same datetime we compare by parts.
*/
return Part - other.Part;
2021-08-25 18:24:44 +02:00
} else {
return comp;
}
}
public JournalFile(string path) {
SetFilename(path);
}
public IEnumerable<Entry> Entries {
get {
if (entries == null || entries.Count == 0) {
try {
LoadEntries();
} catch (IOException) {
entries = new List<Entry>();
}
}
return entries;
}
}
public void LoadEntries() {
List<string> lines = new List<string>();
/* This needs to be done this way, otherwise, if the game is still running the journal files cannot
* be accessed. And it is very much convenient to generate logs while the game is still running.
*/
using (var fs = new FileStream(FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
2021-08-25 18:24:44 +02:00
using (var sr = new StreamReader(fs, Encoding.UTF8)) {
string line = null;
while ((line = sr.ReadLine()) != null) {
lines.Add(line);
}
}
}
entries.Clear();
foreach(var line in lines) {
2022-01-22 13:19:58 +01:00
// Skip empty lines
if (line.Trim().Length == 0) {
continue;
}
2021-08-25 18:24:44 +02:00
Entry entry = Entry.Parse(line);
entries.Add(entry);
}
}
}
}