2021-07-09 11:03:30 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2021-08-25 16:36:57 +02:00
|
|
|
|
using EDJournal;
|
2021-07-09 11:03:30 +02:00
|
|
|
|
|
|
|
|
|
namespace NonaBGS.BGS {
|
|
|
|
|
public class Report {
|
|
|
|
|
private List<Objective> objectives = new List<Objective>();
|
|
|
|
|
|
|
|
|
|
public delegate void OnLogDelegate(string log);
|
|
|
|
|
|
|
|
|
|
public event OnLogDelegate OnLog;
|
|
|
|
|
|
|
|
|
|
public List<Objective> Objectives {
|
|
|
|
|
get { return objectives; }
|
|
|
|
|
set { objectives = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool AddObjective(Objective objective) {
|
2021-07-09 11:30:11 +02:00
|
|
|
|
var found = objectives.Find(x => x.CompareTo(objective) == 0);
|
2021-07-09 11:03:30 +02:00
|
|
|
|
bool added = false;
|
|
|
|
|
|
|
|
|
|
if (found == null) {
|
|
|
|
|
objectives.Add(objective);
|
|
|
|
|
added = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return added;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool IsRelevant(Entry e) {
|
|
|
|
|
return e.Is(Events.MissionCompleted) ||
|
|
|
|
|
e.Is(Events.Docked) ||
|
|
|
|
|
e.Is(Events.FSDJump) ||
|
|
|
|
|
e.Is(Events.MultiSellExplorationData) ||
|
|
|
|
|
e.Is(Events.SellMicroResources) ||
|
2021-09-28 13:20:59 +02:00
|
|
|
|
e.Is(Events.RedeemVoucher) ||
|
2021-09-28 14:41:09 +02:00
|
|
|
|
e.Is(Events.FactionKillBond) ||
|
|
|
|
|
e.Is(Events.MarketSell)
|
2021-07-09 11:03:30 +02:00
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Scan(PlayerJournal journal, DateTime start, DateTime end) {
|
|
|
|
|
var entries = from file in journal.Files
|
|
|
|
|
where file.NormalisedTimestamp >= start && file.NormalisedTimestamp <= end
|
|
|
|
|
select file.Entries
|
|
|
|
|
;
|
|
|
|
|
var relevant = from log in entries.SelectMany(array => array)
|
|
|
|
|
where IsRelevant(log)
|
|
|
|
|
select log
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
string current_system = null;
|
|
|
|
|
string current_station = null;
|
|
|
|
|
string controlling_faction = null;
|
|
|
|
|
|
2021-09-30 13:28:52 +02:00
|
|
|
|
objectives.ForEach(x => x.Clear());
|
2021-07-09 11:03:30 +02:00
|
|
|
|
|
|
|
|
|
foreach (var e in relevant) {
|
|
|
|
|
LogEntry entry = null;
|
2021-08-04 17:50:46 +02:00
|
|
|
|
bool collate = false;
|
2021-07-09 11:03:30 +02:00
|
|
|
|
|
|
|
|
|
if (e.Is(Events.Docked)) {
|
|
|
|
|
/* gleem the current station from this message
|
|
|
|
|
*/
|
|
|
|
|
current_station = (e as DockedEntry).StationName;
|
|
|
|
|
} else if (e.Is(Events.FSDJump)) {
|
2021-07-09 11:39:09 +02:00
|
|
|
|
/* Gleem current system and controlling faction from this message.
|
|
|
|
|
*/
|
2021-07-09 11:03:30 +02:00
|
|
|
|
current_system = (e as FSDJumpEntry).StarSystem;
|
|
|
|
|
controlling_faction = (e as FSDJumpEntry).SystemFaction;
|
|
|
|
|
} else if (e.Is(Events.MissionCompleted)) {
|
|
|
|
|
var completed = e as MissionCompletedEntry;
|
|
|
|
|
entry = new MissionCompleted(completed, current_system, current_station);
|
|
|
|
|
if (completed.HumanReadableNameWasGenerated) {
|
2021-07-09 11:39:09 +02:00
|
|
|
|
/* If the human readable name was generated, we send a log message. Because the
|
|
|
|
|
* generated names all sort of suck, we should have more human readable names in
|
|
|
|
|
* in the lookup dictionary.
|
|
|
|
|
*/
|
2021-07-09 11:03:30 +02:00
|
|
|
|
OnLog?.Invoke("Human readable name for mission \"" +
|
|
|
|
|
completed.Name +
|
|
|
|
|
"\" was generated, please report this.");
|
|
|
|
|
}
|
|
|
|
|
} else if (e.Is(Events.MultiSellExplorationData)) {
|
2021-07-09 11:39:09 +02:00
|
|
|
|
/* For multi-sell-exploraton-data only the controlling faction of the station sold to matters.
|
|
|
|
|
*/
|
2021-07-09 11:03:30 +02:00
|
|
|
|
entry = new Cartographics(e as MultiSellExplorationDataEntry, current_system, current_station);
|
|
|
|
|
entry.Faction = controlling_faction;
|
|
|
|
|
} else if (e.Is(Events.RedeemVoucher)) {
|
2021-07-09 11:39:09 +02:00
|
|
|
|
/* Same for selling combat vouchers. Only the current controlling faction matters here.
|
|
|
|
|
*/
|
2021-07-09 11:03:30 +02:00
|
|
|
|
entry = new Vouchers();
|
|
|
|
|
entry.Entries.Add(e);
|
|
|
|
|
entry.System = current_system;
|
|
|
|
|
entry.Station = current_station;
|
|
|
|
|
entry.Faction = controlling_faction;
|
2021-08-04 17:50:46 +02:00
|
|
|
|
|
2021-09-28 13:20:59 +02:00
|
|
|
|
collate = true;
|
|
|
|
|
} else if (e.Is(Events.FactionKillBond)) {
|
|
|
|
|
entry = new FactionKillBonds();
|
|
|
|
|
entry.Entries.Add(e);
|
|
|
|
|
entry.System = current_system;
|
|
|
|
|
entry.Station = current_station;
|
|
|
|
|
entry.Faction = (e as FactionKillBondEntry).AwardingFaction;
|
|
|
|
|
|
2021-08-04 17:50:46 +02:00
|
|
|
|
collate = true;
|
2021-07-09 11:03:30 +02:00
|
|
|
|
} else if (e.Is(Events.SellMicroResources)) {
|
|
|
|
|
entry = new SellMicroResources(current_system, current_station);
|
2021-09-28 14:41:09 +02:00
|
|
|
|
entry.Entries.Add(e);
|
|
|
|
|
} else if (e.Is(Events.MarketSell)) {
|
|
|
|
|
entry = new SellCargo() {
|
|
|
|
|
Faction = controlling_faction,
|
|
|
|
|
Station = current_station,
|
|
|
|
|
System = current_system
|
|
|
|
|
};
|
|
|
|
|
|
2021-07-09 11:03:30 +02:00
|
|
|
|
entry.Entries.Add(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (entry == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-09 11:39:09 +02:00
|
|
|
|
/* Find all objectives that generally match.
|
|
|
|
|
*/
|
2021-07-09 11:03:30 +02:00
|
|
|
|
var matches = objectives
|
|
|
|
|
.Where(x => x.Matches(entry) > 0)
|
|
|
|
|
.OrderBy(x => x.Matches(entry))
|
|
|
|
|
;
|
|
|
|
|
if (matches == null || matches.Count() <= 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-09 11:39:09 +02:00
|
|
|
|
/* Then select the one that matches the most.
|
|
|
|
|
*/
|
2021-07-09 11:03:30 +02:00
|
|
|
|
var objective = matches
|
|
|
|
|
.OrderBy(x => x.Matches(entry))
|
|
|
|
|
.Reverse()
|
|
|
|
|
.First()
|
|
|
|
|
;
|
|
|
|
|
|
2021-08-04 17:50:46 +02:00
|
|
|
|
if (objective == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LogEntry existing = null;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
existing = objective.LogEntries.Find(x => x.CompareTo(entry) == 0);
|
|
|
|
|
} catch (NotImplementedException) {
|
|
|
|
|
// Equivalent to not having found anything
|
|
|
|
|
existing = null;
|
|
|
|
|
}
|
|
|
|
|
if (collate && existing != null) {
|
|
|
|
|
existing.Entries.Add(e);
|
|
|
|
|
} else if (!collate || existing == null) {
|
2021-07-09 11:03:30 +02:00
|
|
|
|
objective.LogEntries.Add(entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Scan(PlayerJournal journal) {
|
|
|
|
|
Scan(journal, DateTime.Now, DateTime.Now);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|