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; using System.Globalization; using System.Windows.Forms; using System.Windows.Controls.Primitives; namespace EliteBGS; /// /// Interaction logic for MainWindow.xaml /// 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 logtypes = new List() { new NonaDiscordLog(), new GenericDiscordLog(), new OneLineDiscordLog(), }; 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 InitialiseTime(); journallocation.Text = Config.Global.JournalLocation; } private void InitialiseTime() { DateTime today = DateTime.Today; DateTime tomorrow = today.AddDays(1); startdate.CultureInfo = enddate.CultureInfo = CultureInfo.InvariantCulture; startdate.Value = today; enddate.Value = tomorrow; } private void TreeView_CheckBox_Updated(object sender, RoutedEventArgs args) { GenerateLog(); } 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 HandleEntries(List entries, DateTime start, DateTime end) { try { TransactionParser parser = new TransactionParser(); List transactions = parser.Parse(entries); // Filter the transactions down to the given time frame transactions = transactions .Where(t => t.CompletedAtDateTime >= start && t.CompletedAtDateTime <= end) .ToList() ; List incompletes = transactions.OfType().ToList(); // Log incomplete and remove them from the results. foreach (var incomplete in incompletes) { Log(incomplete.Reason); } transactions.RemoveAll(x => incompletes.Contains(x)); 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()); } } private void HandleEntries(List entries) { HandleEntries(entries, startdate.Value ?? DateTime.Now, enddate.Value ?? DateTime.Now); } private void Loadentries_EntriesLoaded(List lines) { HandleEntries(lines); } private void ParseJournal_Click(object sender, RoutedEventArgs e) { try { TransactionParser parser = new TransactionParser(); DateTime start = startdate.Value ?? DateTime.Now; DateTime end = enddate.Value ?? 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); DateTime actualend = end.AddDays(1); List entries = journal.Files .Where(f => f.NormalisedDateTime >= actualstart && f.NormalisedDateTime <= actualend) .SelectMany(e => e.Entries) .ToList() ; HandleEntries(entries, start, end); 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) { RefreshView(); } } private void entries_KeyUp(object sender, System.Windows.Input.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); } private Objective GetObjectiveFromControl(object sender) { System.Windows.Controls.Control control = sender as System.Windows.Controls.Control; if (control == null || control.DataContext == null) { return null; } return control.DataContext as Objective; } private void AddCombatZone_Click(object sender, RoutedEventArgs e) { Objective objective = GetObjectiveFromControl(sender); if (objective == null) { return; } CombatZone zone = new CombatZone { Faction = objective.Faction, System = objective.System, Grade = "Low", Type = "Ship", }; UITransaction uitransaction = new UITransaction(zone); objective.UITransactions.Add(uitransaction); RefreshView(); } private void RefreshView() { entries.Items.Refresh(); GenerateLog(); } 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; } private void Transaction_Initialized(object sender, EventArgs e) { } private TransactionType GetTransaction(object sender) where TransactionType : Transaction { System.Windows.Controls.Control button = sender as System.Windows.Controls.Control; if (button == null || button.DataContext == null) { return null; } UITransaction transaction = button.DataContext as UITransaction; if (transaction == null) { return null; } return transaction.Transaction as TransactionType; } private void Low_Click(object sender, RoutedEventArgs e) { CombatZone transaction = GetTransaction(sender); if (transaction == null) { return; } transaction.Grade = CombatZones.DifficultyLow; RefreshView(); } private void Med_Click(object sender, RoutedEventArgs e) { CombatZone transaction = GetTransaction(sender); if (transaction == null) { return; } transaction.Grade = CombatZones.DifficultyMedium; RefreshView(); } private void High_Click(object sender, RoutedEventArgs e) { CombatZone transaction = GetTransaction(sender); if (transaction == null) { return; } transaction.Grade = CombatZones.DifficultyHigh; RefreshView(); } private void VeryHigh_Click(object sender, RoutedEventArgs e) { CombatZone transaction = GetTransaction(sender); if (transaction == null) { return; } transaction.Grade = CombatZones.DifficultyVeryHigh; RefreshView(); } private void Ground_Click(object sender, RoutedEventArgs e) { CombatZone transaction = GetTransaction(sender); if (transaction == null) { return; } transaction.Type = CombatZones.GroundCombatZone; RefreshView(); } private void Ship_Click(object sender, RoutedEventArgs e) { CombatZone transaction = GetTransaction(sender); if (transaction == null) { return; } transaction.Type = CombatZones.ShipCombatZone; RefreshView(); } private void Thargoid_Click(object sender, RoutedEventArgs e) { CombatZone transaction = GetTransaction(sender); if (transaction == null) { return; } transaction.Type = CombatZones.AXCombatZone; RefreshView(); } private void Profit_LostFocus(object sender, RoutedEventArgs e) { RefreshView(); } private void Profit_KeyUp(object sender, System.Windows.Input.KeyEventArgs e) { if (e.Key == Key.Enter) { RefreshView(); } } private DateTime ResetTimeToZero(DateTime d) { DateTime obj = d; obj = obj.AddHours(d.Hour * -1); obj = obj.AddMinutes(d.Minute * -1); obj = obj.AddSeconds(d.Second * -1); return obj; } private void ResetTime_Click(object sender, RoutedEventArgs e) { DateTime? d = startdate.Value; if (d != null) { startdate.Value = ResetTimeToZero(d.Value); } d = enddate.Value; if (d != null) { enddate.Value = ResetTimeToZero(d.Value); } } private void ToggleAll_Click(object sender, RoutedEventArgs e) { ToggleButton button = sender as ToggleButton; Objective objective = GetObjectiveFromControl(sender); if (objective == null) { return; } objective.UITransactions .ForEach(x => x.IsEnabled = (button.IsChecked ?? true)) ; } }