Archived
1
0

Compare commits

...

29 Commits

Author SHA1 Message Date
f159b29191 fix credit values in report 2021-10-19 17:59:32 +02:00
bc9b98dac4 update readme with broken journal 2021-10-07 21:02:01 +02:00
0ef7062f28 add a logo to the binary file 2021-10-07 20:38:38 +02:00
093ac8ed02 copy readme, images and licence 2021-10-07 09:18:17 +02:00
3eee75e814 fix voucher reporting after indepth BGS discussion on EDC 2021-10-07 09:02:34 +02:00
89fd36b5c4 allow finer edit of resulting log 2021-10-05 21:05:47 +02:00
c8e985cb39 fix finding an entry for collating 2021-09-30 13:32:31 +02:00
dd4cc8ba5f do not remove manually added entries 2021-09-30 13:28:52 +02:00
e724955ec8 fix links harder 2021-09-28 15:08:03 +02:00
3350d88c75 fix link to downloads 2021-09-28 15:06:43 +02:00
ec6b1daf85 add a part of build dependencies 2021-09-28 15:00:55 +02:00
00f7d087ea update screenshots with new button 2021-09-28 14:52:22 +02:00
479fcca851 improve combat zone and faction kill bond reporting 2021-09-28 14:45:39 +02:00
1d747756ac implement selling cargo to controlling faction 2021-09-28 14:41:09 +02:00
3b1fc79dba ship is better than space 2021-09-28 14:23:41 +02:00
4b4b1a1161 update read me for combat zones 2021-09-28 14:21:15 +02:00
0fdd3e2c9a implement combat zones and combat bonds 2021-09-28 14:14:16 +02:00
fcf1802d22 implement support for faction kill bonds 2021-09-28 13:20:59 +02:00
55677f2965 don't output total influence if it is zero 2021-09-24 16:50:30 +02:00
f45f860735 fix wrong end of line in report 2021-09-18 11:58:41 +02:00
acfffe298b fix project include 2021-08-25 18:25:54 +02:00
2d5a3b39e4 update files 2021-08-25 18:21:13 +02:00
ee86365e27 move journal handling to a library 2021-08-25 16:36:57 +02:00
1abeb7af93 add a journal stream to get new events 2021-08-25 12:16:28 +02:00
9d4342a6f8 add a influence total for soft caps 2021-08-22 11:50:43 +02:00
7351401b95 add another mission name 2021-08-22 11:50:33 +02:00
9d7dc7c850 compare faction, system and station case insensitive 2021-08-19 17:14:20 +02:00
1d4058c514 add another mission name 2021-08-19 17:14:02 +02:00
9339eab145 add a few more mission names 2021-08-15 10:40:10 +02:00
44 changed files with 702 additions and 693 deletions

View File

@ -1,11 +1,4 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using NonaBGS.Journal;
using System.Windows;
namespace NonaBGS
{

View File

@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Threading.Tasks;
using NonaBGS.Journal;
using EDJournal;
namespace NonaBGS.BGS {
public class Cartographics : LogEntry {

View File

@ -1,11 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.BGS {
public class CombatZone {
private int level;
public class CombatZone : LogEntry, IComparable {
public string Type { get; set; }
public string Grade { get; set; }
public int Amount { get; set; }
public int CompareTo(object obj) {
if (obj.GetType() != typeof(CombatZone)) {
return -1;
}
var b = obj as CombatZone;
if (b.Faction != Faction || b.System != System) {
return -1; // System and faction don't match
}
if (b.Type != b.Type || b.Grade != b.Grade) {
return -1; // grade and type don't match
}
return 0;
}
public override string ToString() {
return string.Format("Won {0} x {1} {2} Combat Zone(s) for {3}",
Amount, Grade, Type, Faction);
}
}
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.BGS {
namespace NonaBGS.BGS {
public interface IDiscordLogGenerator {
string GenerateDiscordLog(Report report);
}

45
BGS/FactionKillBonds.cs Normal file
View File

@ -0,0 +1,45 @@
using System.Linq;
using System.Globalization;
using EDJournal;
namespace NonaBGS.BGS {
public class FactionKillBonds : LogEntry {
public int TotalSum {
get {
return Entries
.OfType<FactionKillBondEntry>()
.Sum(x => x.Reward)
;
}
}
public string VictimFaction {
get {
return Entries
.OfType<FactionKillBondEntry>()
.First()
.VictimFaction
;
}
}
public override int CompareTo(LogEntry other) {
if (other.GetType() != typeof(FactionKillBonds)) {
return -1;
}
var b = other as FactionKillBonds;
if (b.VictimFaction == VictimFaction) {
return 0;
}
return -1;
}
public override string ToString() {
return string.Format("Faction Kill Bonds: {0} against {1}",
Credits.FormatCredits(TotalSum),
VictimFaction);
}
}
}

View File

@ -1,18 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NonaBGS.Journal;
using EDJournal;
namespace NonaBGS.BGS {
public class LogEntry : IComparable<LogEntry> {
private List<Entry> entries = new List<Entry>();
/// <summary>
/// Controlling faction of the station this entry was made/turned into.
/// </summary>
public string ControllingFaction { get; set; } = "";
public List<Entry> Entries => entries;
public string Station { get; set; }
public string System { get; set; }
public string Faction { get; set; }
/// <summary>
/// Whether this entry was manually added. Manually added entries are not deleted
/// when a new scan is made. Instead they are preserved.
/// </summary>
public bool ManuallyAdded { get; set; }
/// <summary>
/// Whether this entry only benefits the controlling faction or not, default: no

View File

@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NonaBGS.Journal;
using Newtonsoft.Json.Linq;
using System.Text;
using EDJournal;
namespace NonaBGS.BGS {
public class MissionCompleted : LogEntry {

View File

@ -2,9 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Threading.Tasks;
using NonaBGS.Journal;
using EDJournal;
namespace NonaBGS.BGS {
public class NonaDiscordLog : IDiscordLogGenerator {
@ -42,7 +40,27 @@ namespace NonaBGS.BGS {
}
return string.Format("Sold {0} page(s) worth of universal cartographics\n" +
"(Total value: {1} CR)\n", pages, sum);
"(Total value: {1})\n", pages, Credits.FormatCredits(sum));
}
private string BuildCargoSold(Objective objective) {
StringBuilder builder = new StringBuilder();
SellCargo[] sold = objective.LogEntries
.OfType<SellCargo>()
.ToArray()
;
if (sold == null && sold.Length > 0) {
return builder.ToString();
}
foreach (SellCargo sell in sold) {
builder.AppendFormat("{0}\n", sell.ToString());
}
builder.AppendFormat("\n");
return builder.ToString();
}
private string BuildMicroResourcesSold(Objective objective) {
@ -56,7 +74,28 @@ namespace NonaBGS.BGS {
return "";
}
return string.Format("Sold {0} CR worth of Micro Resources\n", sum);
return string.Format("Sold {0} worth of Micro Resources\n",
Credits.FormatCredits(sum));
}
private string BuildKillBonds(Objective objective) {
StringBuilder builder = new StringBuilder();
FactionKillBonds[] bonds = objective.LogEntries
.OfType<FactionKillBonds>()
.ToArray()
;
if (bonds == null || bonds.Length == 0) {
return builder.ToString();
}
foreach (FactionKillBonds bond in bonds) {
builder.AppendFormat("{0}\n", bond.ToString());
}
builder.AppendFormat("\n");
return builder.ToString();
}
private string BuildVouchers(Objective objective) {
@ -73,7 +112,7 @@ namespace NonaBGS.BGS {
foreach (var mission in missions) {
var m = mission as Vouchers;
builder.AppendFormat("Handed in {0} vouchers for {1}\n", m.Type, m.Faction);
builder.AppendFormat("(Total value: {0} CR)\n", m.TotalSum);
builder.AppendFormat("(Total value: {0})\n", Credits.FormatCredits(m.TotalSum));
builder.AppendFormat("\n");
}
@ -83,6 +122,7 @@ namespace NonaBGS.BGS {
private string BuildMissionList(Objective objective) {
Dictionary<string, Dictionary<string, int>> collated = new Dictionary<string, Dictionary<string, int>>();
StringBuilder output = new StringBuilder();
int total_influence = 0;
var missions = from entries in objective.LogEntries
where entries.GetType() == typeof(MissionCompleted)
@ -102,6 +142,8 @@ namespace NonaBGS.BGS {
}
++collated[m.MissionName][m.Influence];
total_influence += m.Influence.Length;
}
foreach (var mission in collated) {
@ -118,9 +160,33 @@ namespace NonaBGS.BGS {
output.Append(")\n\n");
}
if (total_influence > 0) {
output.AppendFormat("Total Influence: {0}\n\n", total_influence);
}
return output.ToString();
}
private string BuildCombatZones(Objective objective) {
StringBuilder builder = new StringBuilder();
CombatZone[] zones = objective.LogEntries
.OfType<CombatZone>()
.ToArray()
;
if (zones == null || zones.Length == 0) {
return builder.ToString();
}
foreach (CombatZone zone in zones) {
builder.AppendFormat("{0}\n", zone.ToString());
}
builder.Append("\n");
return builder.ToString();
}
public string GenerateDiscordLog(Report report) {
StringBuilder log = new StringBuilder();
@ -142,12 +208,21 @@ namespace NonaBGS.BGS {
var vouchers = BuildVouchers(objective);
entries.Append(vouchers);
var zones = BuildCombatZones(objective);
entries.Append(zones);
var bonds = BuildKillBonds(objective);
entries.Append(bonds);
var carto = BuildCartoGraphics(objective);
entries.Append(carto);
var micro = BuildMicroResourcesSold(objective);
entries.Append(micro);
var sold = BuildCargoSold(objective);
entries.Append(sold);
log.Append(entries.ToString().Trim());
log.Append("\n```\n");
}

View File

@ -16,6 +16,12 @@ namespace NonaBGS.BGS {
get => entries;
set => entries = value;
}
public void Clear() {
if (entries == null) {
return;
}
entries.RemoveAll(x => !x.ManuallyAdded);
}
public int Matches(LogEntry e) {
int match_count = 0;
@ -26,19 +32,22 @@ namespace NonaBGS.BGS {
}
}
if (e.System != null && system != null &&
e.System == system) {
++match_count;
if (e.System != null && system != null) {
if (string.Compare(e.System, system, true) == 0) {
++match_count;
}
}
if (e.Station != null && station != null &&
e.Station == station) {
++match_count;
if (e.Station != null && station != null) {
if (string.Compare(e.Station, station, true) == 0) {
++match_count;
}
}
if (e.Faction != null && faction != null &&
e.Faction == faction) {
++match_count;
if (e.Faction != null && faction != null) {
if (string.Compare(e.Faction, faction, true) == 0) {
++match_count;
}
}
return match_count;

View File

@ -1,11 +1,7 @@
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NonaBGS.Journal;
using EDJournal;
namespace NonaBGS.BGS {
public class Report {
@ -38,7 +34,9 @@ namespace NonaBGS.BGS {
e.Is(Events.FSDJump) ||
e.Is(Events.MultiSellExplorationData) ||
e.Is(Events.SellMicroResources) ||
e.Is(Events.RedeemVoucher)
e.Is(Events.RedeemVoucher) ||
e.Is(Events.FactionKillBond) ||
e.Is(Events.MarketSell)
;
}
@ -56,7 +54,7 @@ namespace NonaBGS.BGS {
string current_station = null;
string controlling_faction = null;
this.objectives.ForEach(x => x.LogEntries.Clear());
objectives.ForEach(x => x.Clear());
foreach (var e in relevant) {
LogEntry entry = null;
@ -95,11 +93,25 @@ namespace NonaBGS.BGS {
entry.Entries.Add(e);
entry.System = current_system;
entry.Station = current_station;
entry.Faction = controlling_faction;
entry.Faction = (e as RedeemVoucherEntry).Factions.FirstOrDefault() ?? "";
entry.ControllingFaction = controlling_faction;
collate = true;
} else if (e.Is(Events.SellMicroResources)) {
entry = new SellMicroResources(current_system, current_station);
entry = new SellMicroResources() {
Faction = controlling_faction,
Station = current_station,
System = current_system
};
entry.Entries.Add(e);
} else if (e.Is(Events.MarketSell)) {
entry = new SellCargo() {
Faction = controlling_faction,
Station = current_station,
System = current_system
};
entry.Entries.Add(e);
}
@ -131,12 +143,14 @@ namespace NonaBGS.BGS {
LogEntry existing = null;
try {
existing = objective.LogEntries.Find(x => x.CompareTo(entry) == 0);
} catch (NotImplementedException) {
// Equivalent to not having found anything
existing = null;
}
existing = objective.LogEntries.Find(x => {
try {
return x.CompareTo(entry) == 0;
} catch (NotImplementedException) {
return false;
}
});
if (collate && existing != null) {
existing.Entries.Add(e);
} else if (!collate || existing == null) {

31
BGS/SellCargo.cs Normal file
View File

@ -0,0 +1,31 @@
using System.Text;
using System.Linq;
using EDJournal;
namespace NonaBGS.BGS {
public class SellCargo : LogEntry {
public override string ToString() {
StringBuilder builder = new StringBuilder();
var sold = Entries.OfType<MarketSellEntry>().ToArray();
if (sold == null || sold.Length == 0) {
return builder.ToString();
}
foreach (MarketSellEntry sell in sold) {
builder.AppendFormat("Sold {0} {1} to the {2}\n",
sell.Count,
sell.Type,
sell.BlackMarket ? "Black Market" : "Commodity Market"
);
}
return builder.ToString().Trim();
}
/// <summary>
/// Selling resources to a market only helps the controlling faction
/// </summary>
public override bool OnlyControllingFaction => true;
}
}

View File

@ -1,13 +1,8 @@
using System.Linq;
using NonaBGS.Journal;
using EDJournal;
namespace NonaBGS.BGS {
public class SellMicroResources : LogEntry {
public SellMicroResources(string system, string station) {
System = system;
Station = station;
}
public int TotalSum {
get {
return Entries

View File

@ -1,6 +1,6 @@
using System.Linq;
using System.Globalization;
using NonaBGS.Journal;
using EDJournal;
namespace NonaBGS.BGS {
public class Vouchers : LogEntry {
@ -23,7 +23,13 @@ namespace NonaBGS.BGS {
.GroupBy(x => (x as RedeemVoucherEntry).Type)
.Select(x => x.Key)
.First();
type = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(v);
if (v == "CombatBond") {
type = "Combat Bond";
} else if (v == "bounty") {
type = "Bounty";
} else {
type = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(v);
}
}
return type;
@ -46,10 +52,5 @@ namespace NonaBGS.BGS {
public override string ToString() {
return string.Format("{0} Vouchers: {1}", Type, Credits.FormatCredits(TotalSum));
}
/// <summary>
/// Vouchers only help the controlling faction
/// </summary>
public override bool OnlyControllingFaction => true;
}
}

48
CombatZoneDialog.xaml Normal file
View File

@ -0,0 +1,48 @@
<Window x:Class="NonaBGS.CombatZoneDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NonaBGS"
mc:Ignorable="d"
Title="Add Combat Zone Wins" Height="150" Width="370" Icon="NONA.ico" WindowStartupLocation="CenterOwner">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<GroupBox Header="Add Combat Zone" Grid.Row="0" Grid.Column="0" Width="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox x:Name="type" Grid.Column="0" VerticalAlignment="Top" Width="Auto" IsReadOnly="True" Height="23" Margin="5" SelectedIndex="0">
<ComboBoxItem Content="Ship"/>
<ComboBoxItem Content="On Foot"/>
</ComboBox>
<ComboBox x:Name="grade" Grid.Column="1" VerticalAlignment="Top" IsReadOnly="True" Margin="5" Height="23" Width="Auto" SelectedIndex="0">
<ComboBoxItem Content="Low"/>
<ComboBoxItem Content="Medium"/>
<ComboBoxItem Content="High"/>
</ComboBox>
<TextBox x:Name="amount" Grid.Column="2" Height="23" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="Auto" Margin="5" HorizontalContentAlignment="Right"/>
</Grid>
</GroupBox>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button x:Name="Accept" Content="Accept" HorizontalAlignment="Right" Grid.Column="0" Grid.Row="1" VerticalAlignment="Top" Width="75" Margin="5" IsDefault="True" Click="Accept_Click"/>
<Button x:Name="Cancel" Content="Cancel" HorizontalAlignment="Right" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Width="75" Margin="5" IsCancel="True" Click="Cancel_Click"/>
</Grid>
</Grid>
</Window>

47
CombatZoneDialog.xaml.cs Normal file
View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace NonaBGS {
/// <summary>
/// Interaction logic for CombatZoneDialog.xaml
/// </summary>
public partial class CombatZoneDialog : Window {
public CombatZoneDialog() {
InitializeComponent();
}
public string Type => (type.SelectedItem as ComboBoxItem).Content.ToString();
public string Grade => (grade.SelectedItem as ComboBoxItem).Content.ToString();
public int Amount {
get {
try {
return int.Parse(amount.Text);
} catch (Exception) {
return 1;
}
}
}
private void Accept_Click(object sender, RoutedEventArgs e) {
DialogResult = true;
Close();
}
private void Cancel_Click(object sender, RoutedEventArgs e) {
DialogResult = false;
Close();
}
}
}

View File

@ -1,18 +0,0 @@
using System.Globalization;
namespace NonaBGS.Journal {
public class Credits {
public static string FormatCredits(int amount) {
var format = CultureInfo.CurrentCulture.NumberFormat;
if ((amount % 1000000) == 0) {
amount /= 1000000;
return string.Format("{0}M CR", amount.ToString(format));
} else if ((amount % 1000) == 0) {
amount /= 1000;
return string.Format("{0}K CR", amount.ToString(format));
}
return string.Format("{0} CR", amount.ToString(format));
}
}
}

View File

@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.Journal {
public class DockedEntry : Entry {
public string StationName {
get { return JSON.GetValue("StationName").ToString(); }
}
}
}

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.Journal {
public class EliteDangerous {
/// <summary>
/// The ingame universe is 1286 years in the future. This is needed to convert dates
/// and times to ingame dates and times
/// </summary>
public static readonly int YearOffset = 1286;
}
}

View File

@ -1,88 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace NonaBGS.Journal {
/// <summary>
/// Base class for a single entry within the player journal. If no specific sub class is available
/// this class gives basic information, such as EventType or date when it happened. It also allows
/// base classes access to the underlying JSON object. Base classes should be named after the event
/// type that they map + Entry. So "FSDJump" event is handled by FSDJumpEntry.
/// </summary>
public class Entry {
private static readonly Dictionary<string, Type> classes = new Dictionary<string, Type> {
{ Events.Docked, typeof(DockedEntry) },
{ Events.FSDJump, typeof(FSDJumpEntry) },
{ Events.MissionCompleted, typeof(MissionCompletedEntry) },
{ Events.MultiSellExplorationData, typeof(MultiSellExplorationDataEntry) },
{ Events.MarketSell, typeof(MarketSellEntry) },
{ Events.SellMicroResources, typeof(SellMicroResourcesEntry) },
{ Events.RedeemVoucher, typeof(RedeemVoucherEntry) },
};
private string eventtype = null;
private string datetime = null;
private DateTime timestamp;
private string jsonstr = null;
protected JObject json = null;
public Entry() {
}
public static Entry Parse(string journalline) {
var json = JObject.Parse(journalline);
return Parse(json);
}
public static Entry Parse(JObject json) {
string event_name = json.GetValue("event").ToString();
classes.TryGetValue(event_name, out Type classhandler);
if (classhandler == null) {
classhandler = typeof(Entry);
}
var obj = (Entry)Activator.CreateInstance(classhandler);
obj.InternalInitialise(json);
obj.Initialise();
return obj;
}
private void InternalInitialise(JObject jobject) {
this.json = jobject;
this.jsonstr = json.ToString(formatting: Formatting.None);
this.eventtype = json.GetValue("event").ToString();
this.datetime = json.GetValue("timestamp").ToString();
this.timestamp = DateTime.Parse(this.datetime);
}
protected virtual void Initialise() {
}
public bool Is(string eventtype) {
if (eventtype == null || this.eventtype == null) {
return false;
}
return String.Equals(this.eventtype, eventtype, StringComparison.OrdinalIgnoreCase);
}
public string Event {
get { return eventtype; }
}
public DateTime Timestamp {
get { return timestamp; }
}
public JObject JSON {
get { return this.json; }
}
}
}

View File

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.Journal {
public class Events {
public static readonly string MissionCompleted = "MissionCompleted";
public static readonly string Docked = "Docked";
public static readonly string FSDJump = "FSDJump";
public static readonly string MultiSellExplorationData = "MultiSellExplorationData";
public static readonly string MarketSell = "MarketSell";
public static readonly string SellMicroResources = "SellMicroResources";
public static readonly string RedeemVoucher = "RedeemVoucher";
}
}

View File

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
namespace NonaBGS.Journal {
public class FSDJumpEntry : Entry {
private string starsystem = null;
private string systemfaction = null;
protected override void Initialise() {
starsystem = JSON.Value<string>("StarSystem");
var faction = JSON.Value<JObject>("SystemFaction");
if (faction != null) {
systemfaction = faction.Value<string>("Name");
}
}
public string StarSystem => starsystem;
public string SystemFaction => systemfaction;
}
}

View File

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.Journal {
public class JournalException : Exception {
public JournalException(string message) : base(message) {
}
}
}

View File

@ -1,112 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Globalization;
namespace NonaBGS.Journal
{
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";
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);
}
}
}
}

View File

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.Journal {
public class MarketSellEntry : Entry {
private int totalsale = 0;
protected override void Initialise() {
totalsale = JSON.Value<int>("TotalSale");
}
public int TotalSale => totalsale;
}
}

View File

@ -1,158 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace NonaBGS.Journal {
public class MissionCompletedEntry : Entry {
private Dictionary<string, string> influences = new Dictionary<string, string>();
private string readable_name = null;
private bool readable_name_generated = false;
private string name = null;
private string commodity = null;
private int count = 0;
private int donated = 0;
/* TODO: make this a file at some point for easier editing.
*/
private static readonly Dictionary<string, string> humanreadable = new Dictionary<string, string> {
{ "Mission_AltruismCredits_name", "Donate Credits" },
{ "Mission_AltruismCredits_Bust_name", "Donate Credits (Bust)" },
{ "Mission_Collect_name", "Provide" },
{ "Mission_Collect_CivilLiberty_name", "Provide (Civil Liberty)" },
{ "Mission_Courier_Democracy_name", "Courier (Democracy)" },
{ "Mission_Courier_Elections_name", "Courier (Elections)" },
{ "Mission_Courier_name", "Courier" },
{ "Mission_Courier_RankEmp_name", "Courier (Empire)" },
{ "Mission_Delivery_Boom_name", "Delivery (Boom)" },
{ "Mission_Delivery_Retreat_name", "Delivery (Retreat)" },
{ "Mission_Delivery_name", "Delivery" },
{ "Mission_Delivery_Agriculture_name", "Delivery (Agriculture)" },
{ "Mission_Delivery_RankEmp_name", "Delivery (Imperial Rank)" },
{ "Mission_HackMegaship_name", "Hack Megaship" },
{ "Mission_Hack_BLOPS_Boom_name", "Hack Megaship (Black Ops)" },
{ "Mission_MassacreWing_name", "Massacre (Wing)" },
{ "Mission_Massacre_RankEmp_name", "Massacre (Imperial Navy)" },
{ "Mission_OnFoot_Collect_MB_name", "On Foot Collection" },
{ "Mission_OnFoot_Onslaught_MB_name", "On Foot Onslaught" },
{ "Mission_OnFoot_Onslaught_Offline_MB_name", "On Foot Onslaught (Offline)" },
{ "Mission_OnFoot_RebootRestore_MB_name", "On Foot Reboot/Restore" },
{ "Mission_OnFoot_Reboot_MB_name", "On Foot Reboot" },
{ "Mission_OnFoot_Salvage_MB_name", "On Foot Salvage" },
{ "Mission_Rescue_Planet_name", "Planet Rescue" },
{ "Mission_Salvage_name", "Salvage" },
{ "MISSION_Salvage_CivilUnrest_name", "Salvage (Civil Unrest)" },
{ "MISSION_Salvage_Illegal_name", "Salvage (Illegal)" },
{ "MISSION_Salvage_Retreat_name", "Salvage (Retreat)" },
{ "MISSION_Salvage_Expansion_name", "Salvage (Expansion)" },
{ "Mission_Salvage_RankEmp_name", "Salvage (Imperial Navy)" },
{ "MISSION_Scan_name", "Scan" },
};
protected override void Initialise() {
MakeHumanReadableName();
name = JSON.Value<string>("Name");
if (JSON.ContainsKey("Commodity_Localised")) {
commodity = JSON.Value<string>("Commodity_Localised");
}
if (JSON.ContainsKey("Count")) {
count = JSON.Value<int>("Count");
}
if (JSON.ContainsKey("Donated")) {
donated = JSON.Value<int>("Donated");
}
}
public string Name => name;
public string Commodity => commodity;
public int Count => count;
private void MakeHumanReadableName() {
if (readable_name != null && readable_name.Length > 0) {
return;
}
if (Name == null) {
return;
}
StringBuilder builder;
if (humanreadable.ContainsKey(Name)) {
builder = new StringBuilder(humanreadable[Name]);
readable_name_generated = false;
} else {
builder = new StringBuilder(Name);
builder.Replace("Mission_", "");
builder.Replace("_name", "");
builder.Replace("_MB", "");
builder.Replace('_', ' ');
builder.Replace("Illegal", " (Illegal)");
builder.Replace("OnFoot", "On Foot");
builder.Replace(" BS", "");
builder.Replace("HackMegaship", "Hack Megaship");
builder.Replace("Boom", "");
builder.Replace("RebootRestore", "Reboot/Restore");
builder.Replace("CivilLiberty", "");
readable_name_generated = true;
}
if (count > 0 && commodity != null) {
builder.AppendFormat(" ({0} {1})", count, commodity);
}
if (donated > 0) {
builder.AppendFormat(" ({0})", Credits.FormatCredits(donated));
}
readable_name = builder.ToString().Trim();
}
public string HumanReadableName {
get {
MakeHumanReadableName();
return readable_name;
}
}
public bool HumanReadableNameWasGenerated {
get {
MakeHumanReadableName();
return readable_name_generated;
}
}
public string GetInfluenceForFaction(string faction) {
if (influences.ContainsKey(faction)) {
return influences[faction];
}
var effects = JSON.Value<JArray>("FactionEffects");
foreach (var effect in effects.Children<JObject>()) {
if (effect.GetValue("Faction").ToString() != faction) {
continue;
}
var influence = effect.Value<JArray>("Influence");
if (influence == null || influence.Count == 0) {
// No influence reward, happens on courier missions sometimes.
// There is always one point of rep, even if the mission won't state it
influences.Add(faction, "+");
}
foreach (var infl in influence.Children<JObject>()) {
infl.TryGetValue("Influence", out JToken result);
if (result != null && result.Type == JTokenType.String) {
influences.Add(faction, result.ToString());
return result.ToString();
}
}
}
return "";
}
}
}

View File

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.Journal {
public class MultiSellExplorationDataEntry : Entry {
private int totalearnings = 0;
protected override void Initialise() {
totalearnings = JSON.Value<int>("TotalEarnings");
}
public int TotalEarnings => totalearnings;
}
}

View File

@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.Journal {
public class PlayerJournal {
public static string DefaultPath = "%UserProfile%\\Saved Games\\Frontier Developments\\Elite Dangerous";
private List<JournalFile> journalfiles = new List<JournalFile>();
private string basepath = null;
public PlayerJournal() {
Initialise(DefaultPath);
}
public PlayerJournal(string path) {
Initialise(path);
}
private void Initialise(string path) {
basepath = Environment.ExpandEnvironmentVariables(path);
}
public List<JournalFile> Files {
get { return journalfiles; }
}
public void Open() {
if (!Directory.Exists(basepath)) {
throw new JournalException("Invalid base path, path could not be found");
}
this.ScanFiles();
}
public void ScanFiles() {
var files = Directory.EnumerateFiles(basepath);
journalfiles.Clear();
foreach (var file in files) {
string full = Path.Combine(basepath, file);
try {
JournalFile journalfile = new JournalFile(full);
journalfiles.Add(journalfile);
} catch (JournalException) {
/* invalid journal file, or one of the other json files in there */
continue;
}
}
journalfiles.Sort();
}
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.Journal {
public class RedeemVoucherEntry : Entry {
private int amount = 0;
private string type = null;
protected override void Initialise() {
amount = JSON.Value<int>("Amount");
type = JSON.Value<string>("Type");
}
public int Amount => amount;
public string Type => type;
}
}

View File

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NonaBGS.Journal {
public class SellMicroResourcesEntry : Entry {
private int price;
protected override void Initialise() {
price = JSON.Value<int>("Price");
}
public int Price => price;
}
}

View File

@ -7,7 +7,7 @@
xmlns:local="clr-namespace:NonaBGS"
xmlns:BGS="clr-namespace:NonaBGS.BGS" xmlns:Util="clr-namespace:NonaBGS.Util" d:DataContext="{d:DesignInstance Type=Util:AppConfig}" x:Name="window" x:Class="NonaBGS.MainWindow"
mc:Ignorable="d"
Title="Nova Navy BGS Helper" Height="513.8" Width="885.658">
Title="Nova Navy BGS Helper" Height="520" Width="890" Icon="NONA.ico">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
@ -37,6 +37,8 @@
<abc:AutoCompleteTextBox x:Name="faction" Margin="0" VerticalAlignment="Center" MinWidth="120" MinHeight="22" KeyDown="Filter_KeyDown"/>
<Separator Height="26.2857142857143" Margin="0" VerticalAlignment="Top"/>
<Button x:Name="AddFilter" Content="Add Objective" VerticalAlignment="Stretch" Click="AddFilter_Click" Margin="0,0,0,0.286" RenderTransformOrigin="0.5,0.505"/>
<Separator Height="26.2857142857143" Margin="0" VerticalAlignment="Top"/>
<Button x:Name="AddCombatZone" Content="Add Combat Zone Win" VerticalAlignment="Stretch" Margin="0,0,0,0.286" RenderTransformOrigin="0.5,0.505" Click="AddCombatZone_Click"/>
</ToolBar>
<ToolBar VerticalAlignment="Top" Grid.Row="1" Width="Auto" Margin="0,0,0,0" Height="Auto" Grid.ColumnSpan="3" HorizontalAlignment="Left">
<Button x:Name="ParseJournal" Content="Parse Journal" VerticalAlignment="Center" Click="ParseJournal_Click" HorizontalAlignment="Center"/>
@ -62,7 +64,7 @@
<ToolBar HorizontalAlignment="Left" Height="36" VerticalAlignment="Top" Width="Auto">
<Button x:Name="GenerateDiscord" Content="Genereate Discord Report" VerticalAlignment="Center" Margin="0,0,0,4.857" Click="GenerateDiscord_Click" Height="26"/>
</ToolBar>
<TextBox x:Name="DiscordLog" Height="Auto" Margin="0,0,-0.285,-0.429" TextWrapping="Wrap" FontFamily="Consolas" FontSize="14" Grid.Row="1" Grid.ColumnSpan="2"/>
<TextBox x:Name="DiscordLog" Height="Auto" TextWrapping="Wrap" FontFamily="Consolas" FontSize="14" Grid.Row="1" Grid.ColumnSpan="2" AcceptsReturn="True" AcceptsTab="True"/>
</Grid>
</TabItem>
<TabItem Header="Settings" HorizontalAlignment="Left" Height="20" VerticalAlignment="Top" Width="53.7142857142857">

View File

@ -5,7 +5,8 @@ using System.Windows.Controls;
using System.Windows.Input;
using Ookii.Dialogs.Wpf;
using NonaBGS.Journal;
using EDJournal;
using NonaBGS.BGS;
using NonaBGS.Util;
using NonaBGS.EDDB;
@ -240,5 +241,40 @@ namespace NonaBGS {
dialog.StartDownload();
dialog.ShowDialog();
}
private void AddCombatZone_Click(object sender, RoutedEventArgs e) {
if (entries.SelectedItem == null) {
return;
}
TreeViewItem item = entries.SelectedItem as TreeViewItem;
var obj = item.Tag;
if (obj.GetType() != typeof(Objective)) {
return;
}
Objective objective = obj as Objective;
CombatZoneDialog dialog = new CombatZoneDialog() { Owner = this };
if (!(dialog.ShowDialog() ?? false)) {
return;
}
CombatZone zone = new CombatZone();
zone.ManuallyAdded = true;
zone.Faction = objective.Faction;
zone.System = objective.System;
zone.Station = objective.Station;
zone.Grade = dialog.Grade;
zone.Type = dialog.Type;
zone.Amount = dialog.Amount;
objective.LogEntries.Add(zone);
RefreshObjectives();
}
}
}

BIN
NONA.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

View File

@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NonaBGS"
mc:Ignorable="d"
Title="Progress" Height="100" Width="450">
Title="Progress" Height="100" Width="450" Icon="NONA.ico">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />

View File

@ -1,6 +1,6 @@
# NonaBGS
This tool is meant to help people contributing to the Novay Navy BGS effor to create
This tool is meant to help people contributing to the Nova Navy BGS effor to create
BGS reports. The tool allows you to configure BGS objectives, and will then parse your
player journal for tasks you completed relating to that BGS objective. Once the JSON
player journal has been parsed, you may then generate a BGS report for the Nova Navy
@ -8,7 +8,7 @@ discord.
Source code is available [here](https://git.aror.org/florian/nonabgs).
Binary downloads can be found here: [https://bgs.aror.org/](https://bgs.aror.org/).
Binary downloads can be found here: [https://bgs.n0la.org/](https://bgs.n0la.org/).
## How To
@ -27,11 +27,19 @@ recognises the following completed tasks:
* Vouchers, including bounty vouchers, combat bonds, and settlement vouchers (aka intel packages)
* Selling of micro resources (Odyssey only)
* Selling cartography data
* Selling of cargo to stations
Please note that cartography data, micro resources, and vouchers only help the controlling faction
Please note that cartography data, and micro resources only help the controlling faction
of a station. The tool is clever enough to exclude these if the station you turn them in at, is not
controlled by the faction you specified in the objective.
There is no entry in the journal if you win a combat zone. So you have to add those manually. Select
an objective for which you wish to log a combat zone. The faction in the objective, must be the
faction you fought for in the combat zone. Then click "Add Combat Zone Win". Select type,
either "On Foot" for Odyssey, or "Ship" for regular ones. Then select the grade (low, medium or
high), and how many you won. Then press "Accept". Select "Cancel" to abort. You can of course remove
the combat zone entries by selecting them, and pressing "DEL".
![Main Window with entries](main-entries.png)
The window will then list all the journal entries it has found, and group them by objectives. You
@ -46,6 +54,41 @@ The resulting discord report is kept in the Nova Navy format. Before you copy/pa
Nova Navy discord, you should check the log. You can of course edit it, if something is wrong
or the tool itself missed something.
## Known Issues and Bugs
Settlement vouchers (aka Intel Packages) help every faction aligned with the given superpower.
So if you turn in an Imperial intel package on an imperial station, all factions aligned with
the Empire will gain a bit of INF boost. The tool currently cannot handle that. All intel packages
are displayed instead.
Sometimes bounty vouchers are not properly recognised. This is a bug in the player journal, where
the faction information is not properly written out in the journal:
```
{
"timestamp":"2021-10-07T14:57:50Z", "event":"RedeemVoucher",
"Type":"bounty", "Amount":20750,
"Factions":[ { "Faction":"", "Amount":500 }, { "Faction":"", "Amount":20250 }]
}
```
Since the tool does not know for which faction these bounties were redeemed for, it cannot assign
it to an objective.
The player journal currently does not make an entry when you win or lose a combat zone. This is a
an ommission from FDev:
* [https://issues.frontierstore.net/issue-detail/43509](https://issues.frontierstore.net/issue-detail/43509)
Please upvote the issue to get it fixed. Until then, you have to add combat zone wins manually.
Also missions accepted from NPCs in Odyssey concourses do not get a player journal entry. This is
also an ommission from FDev:
* [https://issues.frontierstore.net/issue-detail/43586](https://issues.frontierstore.net/issue-detail/43586)
Until this is fixed, please edit the resulting BGS log text, and manually add such entries.
## Use EDDB information
NonaBGS can download information from EDDB to auto complete system- and station names. You can
@ -65,6 +108,16 @@ helpful if you included the JSON player journal. This player journal can be foun
%userprofile%\saved Games\Frontier Developments\Elite Dangerous\
```
## Build Dependencies
Handling of Elite Dangerous player journals have been moved to a separate project called `EDJournal`.
Its source can be found [here](https://git.aror.org/florian/edjournal). This project simply depends
on the binary DLL that `EDJournal` builds.
The project also requires `Ookii.Dialogs.WPF` controls, which contains the auto complete text box.
And of course, `Newtonsoft.Json` as the JSON parser.
## About
This tool was made by CMDR Hekateh (Discord: `nola#2457`) of the Nova Navy.

73
Resources.Designer.cs generated Normal file
View File

@ -0,0 +1,73 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace NonaBGS {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NonaBGS.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon NONA {
get {
object obj = ResourceManager.GetObject("NONA", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
}
}

124
Resources.resx Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="NONA" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\NONA.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

BIN
Resources/NONA.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

View File

@ -1,9 +1,4 @@
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespace NonaBGS.Util {
public class AppConfig : INotifyPropertyChanged {

BIN
logo_v4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
logo_v4_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -7,7 +7,7 @@
<ProjectGuid>{73BFB315-C808-40E7-8D69-B651F875880C}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>NonaBGS</RootNamespace>
<AssemblyName>nonabgs</AssemblyName>
<AssemblyName>NonaBGS</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
@ -37,10 +37,17 @@
<PropertyGroup>
<StartupObject>NonaBGSApplication</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>NONA.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="AutoCompleteTextBox, Version=1.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\AutoCompleteTextBox.1.1.1\lib\net472\AutoCompleteTextBox.dll</HintPath>
</Reference>
<Reference Include="EDJournal, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\edjournal\bin\Debug\EDJournal.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
@ -72,15 +79,16 @@
</ApplicationDefinition>
<Compile Include="BGS\DiscordLogGenerator.cs" />
<Compile Include="BGS\NonaDiscordLog.cs" />
<Compile Include="BGS\SellCargo.cs" />
<Compile Include="BGS\SellMicroResources.cs" />
<Compile Include="BGS\FactionKillBonds.cs" />
<Compile Include="EDDB\PopulatedSystems.cs" />
<Compile Include="EDDB\Stations.cs" />
<Compile Include="Journal\Credits.cs" />
<Compile Include="Journal\EliteDangerous.cs" />
<Compile Include="Journal\MarketSellEntry.cs" />
<Compile Include="Journal\MultiSellExplorationDataEntry.cs" />
<Compile Include="Journal\RedeemVoucherEntry.cs" />
<Compile Include="Journal\SellMicroResourcesEntry.cs" />
<Compile Include="Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="UI\StationSuggestionProvider.cs" />
<Compile Include="UI\SystemSuggestionProvider.cs" />
<Compile Include="Util\AppConfig.cs" />
@ -89,6 +97,9 @@
<Compile Include="ProgressDialog.xaml.cs">
<DependentUpon>ProgressDialog.xaml</DependentUpon>
</Compile>
<Compile Include="CombatZoneDialog.xaml.cs">
<DependentUpon>CombatZoneDialog.xaml</DependentUpon>
</Compile>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@ -103,15 +114,7 @@
<Compile Include="BGS\CombatZone.cs" />
<Compile Include="BGS\LogEntry.cs" />
<Compile Include="BGS\MissionCompleted.cs" />
<Compile Include="Journal\DockedEntry.cs" />
<Compile Include="Journal\Entry.cs" />
<Compile Include="BGS\Objective.cs" />
<Compile Include="Journal\Events.cs" />
<Compile Include="Journal\FSDJumpEntry.cs" />
<Compile Include="Journal\JournalException.cs" />
<Compile Include="Journal\JournalFile.cs" />
<Compile Include="Journal\MissionCompletedEntry.cs" />
<Compile Include="Journal\PlayerJournal.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
@ -120,6 +123,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="CombatZoneDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
@ -135,6 +142,10 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
@ -144,22 +155,42 @@
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="README.md" />
<None Include="README.md">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Resource Include="main-objectives.png" />
<Resource Include="main-objectives.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
</ItemGroup>
<ItemGroup>
<Resource Include="main-entries.png" />
<Resource Include="main-entries.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
</ItemGroup>
<ItemGroup>
<Resource Include="main-report.png" />
<Resource Include="main-report.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
</ItemGroup>
<ItemGroup>
<Resource Include="LICENCE.txt" />
<Resource Include="LICENCE.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
</ItemGroup>
<ItemGroup>
<Resource Include="logo_v4.png" />
<Resource Include="logo_v4_bg.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\NONA.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="NONA.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -15,6 +15,10 @@ Global
{73BFB315-C808-40E7-8D69-B651F875880C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{73BFB315-C808-40E7-8D69-B651F875880C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{73BFB315-C808-40E7-8D69-B651F875880C}.Release|Any CPU.Build.0 = Release|Any CPU
{C84BD6A6-55AF-48F0-A73E-51D1FAF65BC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C84BD6A6-55AF-48F0-A73E-51D1FAF65BC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C84BD6A6-55AF-48F0-A73E-51D1FAF65BC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C84BD6A6-55AF-48F0-A73E-51D1FAF65BC2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE