EDBGS/EliteBGS/MainWindow.xaml.cs

315 lines
9.8 KiB
C#
Raw Normal View History

2022-11-24 19:38:19 +01:00
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Ookii.Dialogs.Wpf;
using EDPlayerJournal;
using EDPlayerJournal.BGS;
using EDPlayerJournal.Entries;
using EliteBGS.BGS;
using EliteBGS.Util;
namespace EliteBGS;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
private PlayerJournal journal;
private Report report;
public Config Config { get; set; } = new Config();
private LoadEntriesWindow loadentries = null;
private static readonly List<DiscordLogGenerator> logtypes = new List<DiscordLogGenerator>() {
new NonaDiscordLog(),
new GenericDiscordLog(),
};
public MainWindow() {
InitializeComponent();
try {
Config.LoadGlobal();
} catch (Exception) {
/* ignored */
}
foreach (DiscordLogGenerator type in logtypes) {
LogType.Items.Add(type);
}
string lastused = Config.Global.LastUsedDiscordTemplate;
int lastindex = logtypes.FindIndex(x => x.ToString() == lastused);
if (lastindex > -1) {
LogType.SelectedIndex = lastindex;
} else {
LogType.SelectedIndex = 0;
}
journal = new PlayerJournal(Config.Global.JournalLocation);
// Set both to now
startdate.SelectedDate = DateTime.Now;
enddate.SelectedDate = DateTime.Now;
journallocation.Text = Config.Global.JournalLocation;
}
private void TreeView_CheckBox_Updated(object sender, RoutedEventArgs args) {
GenerateLog();
}
2022-11-25 15:58:06 +01:00
private void HandleEntries(List<Entry> entries) {
2022-11-24 19:38:19 +01:00
try {
TransactionParser parser = new TransactionParser();
2022-11-25 15:58:06 +01:00
List<Transaction> transactions = parser.Parse(entries);
// Log incomplete and remove them from the results.
foreach (var incomplete in transactions.OfType<IncompleteTransaction>()) {
Log(incomplete.Reason);
transactions.Remove(incomplete);
}
2022-11-24 19:38:19 +01:00
report = new Report(transactions);
this.entries.ItemsSource = report.Objectives;
} catch (Exception exception) {
Log("Something went terribly wrong while parsing the E:D player journal.");
Log("Please send this to CMDR Hekateh:");
Log(exception.ToString());
}
}
2022-11-25 15:58:06 +01:00
private void Loadentries_EntriesLoaded(List<Entry> lines) {
HandleEntries(lines);
}
2022-11-24 19:38:19 +01:00
private void Report_OnLog(string message) {
StringBuilder builder = new StringBuilder();
builder.Append(DateTime.Now.ToString());
builder.Append(": ");
builder.Append(message);
builder.Append("\n");
log.AppendText(builder.ToString());
}
private void Log(string message) {
Report_OnLog(message);
}
private void ParseJournal_Click(object sender, RoutedEventArgs e) {
try {
TransactionParser parser = new TransactionParser();
DateTime start = startdate.SelectedDate ?? DateTime.Now;
DateTime end = enddate.SelectedDate ?? DateTime.Now;
journal.Open(); // Load all files
// Log files only get rotated if you restart the game client. This means that there might
// be - say - entries from the 4th of May in the file with a timestamp of 3rd of May. This
// happens if you happen to play a session late into the night.
// At first I tried extracting the first and last line of a file to see the date range, but
// if you have a lot of files this becomes quite slow, and quite the memory hog (as journal
// files have to be read in their entirety to check this). So we assume that you can't play
// three days straight, and keep the code fast.
DateTime actualstart = start.AddDays(-3);
List<Entry> entries = journal.Files
.Where(f => f.NormalisedDateTime >= actualstart && f.NormalisedDateTime <= end)
.SelectMany(e => e.Entries)
.ToList()
;
// Now further sort the list down to entries that are actually within the given datetime
// Note that entry datetimes are not normalised, so we have to sort until end + 1 day
DateTime actualend = end.AddDays(1);
entries = entries
.Where(e => e.Timestamp >= start && e.Timestamp < actualend)
.ToList()
;
2022-11-25 15:58:06 +01:00
HandleEntries(entries);
2022-11-24 19:38:19 +01:00
GenerateLog();
} catch (Exception exception) {
Log("Something went terribly wrong while parsing the E:D player journal.");
Log("Please send this to CMDR Hekateh:");
Log(exception.ToString());
}
}
private void GenerateLog() {
try {
DiscordLogGenerator discord = LogType.SelectedItem as DiscordLogGenerator;
string report = discord.GenerateDiscordLog(this.report);
DiscordLog.Text = report;
} catch (Exception exception) {
Log("Something went terribly wrong while generating the Discord log.");
Log("Please send this to CMDR Hekateh:");
Log(exception.ToString());
}
}
private void GenerateDiscord_Click(object sender, RoutedEventArgs e) {
GenerateLog();
}
private void RemoveCurrentObjective() {
if (entries.SelectedItem == null) {
return;
}
object obj = entries.SelectedItem;
bool removed = false;
if (obj.GetType() == typeof(Objective)) {
removed = report.Objectives.Remove(obj as Objective);
} else if (obj.GetType() == typeof(UITransaction) ||
obj.GetType().IsSubclassOf(typeof(UITransaction))) {
foreach (Objective parent in report.Objectives) {
if (parent.UITransactions.Remove(obj as UITransaction)) {
removed = true;
}
}
}
if (removed) {
2022-11-25 16:03:32 +01:00
RefreshView();
2022-11-24 19:38:19 +01:00
}
}
private void entries_KeyUp(object sender, KeyEventArgs e) {
if (e.Key == Key.Delete) {
RemoveCurrentObjective();
}
}
private void browsejournallocation_Click(object sender, RoutedEventArgs e) {
var dialog = new VistaFolderBrowserDialog();
if ((bool)!dialog.ShowDialog()) {
return;
}
Config.Global.JournalLocation = dialog.SelectedPath;
journallocation.Text = Config.Global.JournalLocation;
journal = new PlayerJournal(Config.Global.JournalLocation);
}
/// <summary>
/// Gets the currently selected objective, even if a log entry in said objective
/// is selected instead. If nothing is selected, returns null.
/// </summary>
/// <returns></returns>
private Objective GetSelectedObjective() {
var obj = entries.SelectedItem;
if (obj == null) {
return null;
}
if (obj.GetType() == typeof(Objective)) {
return obj as Objective;
}
// Some form of entry perhaps?
if (obj.GetType().IsSubclassOf(typeof(Transaction))) {
Transaction entry = obj as Transaction;
Objective objective = entries.Items
.OfType<Objective>()
.First(x => x.Transactions.Contains(entry))
;
return objective;
}
return null;
}
private void AddCombatZone_Click(object sender, RoutedEventArgs e) {
Objective objective = GetSelectedObjective();
if (objective == null) {
return;
}
CombatZoneDialog dialog = new CombatZoneDialog() { Owner = this };
if (!(dialog.ShowDialog() ?? false)) {
return;
}
CombatZone zone = new CombatZone {
Faction = objective.Faction,
System = objective.System,
Grade = dialog.Grade,
Type = dialog.Type,
Amount = dialog.Amount
};
objective.Transactions.Add(zone);
2022-11-25 16:03:32 +01:00
RefreshView();
}
private void RefreshView() {
entries.Items.Refresh();
2022-11-24 19:38:19 +01:00
GenerateLog();
}
private void AdjustProfit_Click(object sender, RoutedEventArgs e) {
if (entries.SelectedItem == null || entries.SelectedItem.GetType() != typeof(SellCargo)) {
return;
}
SellCargo sell = entries.SelectedItem as SellCargo;
AdjustProfitWindow adjust = new AdjustProfitWindow() { Owner = this };
adjust.Profit.Text = sell.Profit.ToString();
if (!(adjust.ShowDialog() ?? false)) {
return;
}
if (int.TryParse(adjust.Profit.Text, out int newprofit)) {
sell.Profit = newprofit;
2022-11-25 16:03:32 +01:00
RefreshView();
2022-11-24 19:38:19 +01:00
}
}
private void LogType_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (LogType.SelectedItem == null) {
return;
}
string template = LogType.SelectedItem.ToString();
Config.Global.LastUsedDiscordTemplate = template;
GenerateLog();
}
private void ManuallyParse_Click(object sender, RoutedEventArgs e) {
if (loadentries != null) {
loadentries.Show();
return;
}
loadentries = new LoadEntriesWindow();
loadentries.Closed += Loadentries_Closed;
loadentries.EntriesLoaded += Loadentries_EntriesLoaded;
loadentries.Show();
}
private void Loadentries_Closed(object sender, EventArgs e) {
loadentries = null;
}
private void window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
loadentries?.Close();
loadentries = null;
}
}