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>
|
|
|
|
|
{
|
|
|
|
|
private string fullpath = null;
|
|
|
|
|
private string part = null;
|
|
|
|
|
private int intpart = 0;
|
|
|
|
|
private DateTime datetime;
|
|
|
|
|
private DateTime normalised;
|
|
|
|
|
private List<Entry> entries = new List<Entry>();
|
|
|
|
|
|
|
|
|
|
private static Regex fileregex = new Regex("Journal\\.(\\d+)\\.(\\d+)\\.log");
|
|
|
|
|
private static string iso8601 = "yyyyMMddTHHmmss";
|
|
|
|
|
private static string iso8601_notime = "yyyyMMdd";
|
|
|
|
|
|
2021-08-27 19:33:01 +02:00
|
|
|
|
public string FullPath => fullpath;
|
|
|
|
|
|
2021-08-25 18:24:44 +02:00
|
|
|
|
public static bool VerifyFile(string path) {
|
|
|
|
|
string filename = Path.GetFileName(path);
|
|
|
|
|
|
|
|
|
|
var matches = fileregex.Matches(filename);
|
|
|
|
|
return matches.Count != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 < 1) {
|
|
|
|
|
throw new JournalException(string.Format("Invalid journal file: {0}", filename));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.fullpath = path;
|
|
|
|
|
this.part = matches[0].Groups[2].ToString();
|
|
|
|
|
this.intpart = int.Parse(part);
|
|
|
|
|
// 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(matches[0].Groups[1].ToString());
|
|
|
|
|
date.Insert(8, "T"); // Add the "T" separating date and time
|
|
|
|
|
this.datetime = DateTime.ParseExact(date.ToString(), iso8601, CultureInfo.InvariantCulture);
|
|
|
|
|
this.normalised = DateTime.Parse(this.datetime.ToShortDateString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int CompareTo(JournalFile other) {
|
|
|
|
|
if (datetime == null || other.datetime == null) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
var comp = DateTime.Compare(datetime, other.datetime);
|
|
|
|
|
if (comp == 0) {
|
|
|
|
|
/* If we have the exact same datetime we compare by parts.
|
|
|
|
|
*/
|
|
|
|
|
return intpart - other.intpart;
|
|
|
|
|
} else {
|
|
|
|
|
return comp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public JournalFile(string path) {
|
|
|
|
|
SetFilename(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DateTime Timestamp {
|
|
|
|
|
get { return datetime; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DateTime NormalisedTimestamp {
|
|
|
|
|
get { return normalised; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Part {
|
|
|
|
|
get { return intpart; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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(this.fullpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
|
|
|
|
|
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) {
|
|
|
|
|
Entry entry = Entry.Parse(line);
|
|
|
|
|
entries.Add(entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|