16 Commits
0.3.4 ... 0.3.6

Author SHA1 Message Date
d6e2280a00 update website 2023-10-25 11:39:39 +02:00
160f4f8370 bump version information 2023-10-25 11:38:56 +02:00
4400418d30 update changelog 2023-10-25 11:38:47 +02:00
43037b0a5b don't return null for unknown 2023-10-25 11:35:30 +02:00
afc831cf31 add the new banshee 2023-10-25 11:35:19 +02:00
4ab54ee576 show Errors found by journal parser 2023-10-25 11:30:44 +02:00
d6842115c5 no longer completely fail on one wrong entry
U17 might have caused some journal bugs so don't fail immediately on one wrong entry, instead keep them in an Errors collection for later processing
2023-10-25 11:30:34 +02:00
acb60e0a08 bump version 2023-09-11 10:51:17 +02:00
dac9b7b8c7 bump assembly version 2023-09-08 11:51:51 +02:00
3338f573c8 update changelog 2023-09-08 11:50:00 +02:00
204d6b8914 rename glaive to hunter
Glaive and Scythe can no longer be distinguished from the bounty claims you get.
2023-09-08 11:49:55 +02:00
4c75515a70 include failed missions in mission format
Since we now have to calculate negative INF with the normal INF (in case both happens), mission formatter now also handles failed missions.
2023-09-08 11:43:05 +02:00
c43c6f742a introduce negative influence
Sometimes missions actually tell us how much negative influence a faction got through secondary influences. We now count this, and present is as negative influence via minuses. Summaries have been updated to reflect this change.
2023-09-08 11:20:49 +02:00
c7a70598c4 don't lose small credit amounts in formatting 2023-09-08 10:21:10 +02:00
cdd7eb33de add settlements for ground CZs to the combat log 2023-08-26 10:53:25 +02:00
dab39b9a4e fix note in FAQ 2023-06-25 19:27:44 +02:00
29 changed files with 345 additions and 118 deletions

View File

@@ -43,6 +43,12 @@ public class CombatZone : Transaction {
/// </summary>
public bool? CapitalShip { get; set; }
/// <summary>
/// If we have a combat zone, this might point to the settlement
/// in question.
/// </summary>
public string? Settlement { get; set; }
/// <summary>
/// How many optional objectives were completed?
/// </summary>

View File

@@ -9,7 +9,7 @@ namespace EDPlayerJournal.BGS;
/// faction to another. Both sometimes gain influence.
/// </summary>
public class InfluenceSupport : Transaction {
public string Influence { get; set; } = "";
public MissionInfluence? Influence { get; set; } = null;
/// <summary>
/// Relevant mission completed entry
@@ -46,7 +46,7 @@ public class InfluenceSupport : Transaction {
builder.AppendFormat("Influence gained from \"{0}\": \"{1}\"",
missionname,
string.IsNullOrEmpty(Influence) ? "NONE" : Influence
Influence == null ? "NONE" : Influence.TrendAdjustedInfluence
);
return builder.ToString();

View File

@@ -38,7 +38,14 @@ public class MissionCompleted : Transaction {
return "";
}
return (CompletedEntry.Mission.GetInfluenceForFaction(Faction, SystemAddress) ?? "");
return string.Join("",
CompletedEntry
.Mission
.GetInfluenceForFaction(Faction, SystemAddress)
.Select(x => x.Influence)
.ToArray()
)
;
}
}
@@ -70,8 +77,10 @@ public class MissionCompleted : Transaction {
var influence = CompletedEntry.Mission.GetInfluenceForFaction(Faction, SystemAddress);
builder.AppendFormat("{0}", MissionName);
if (influence != "") {
builder.AppendFormat(", Influence: {0}", influence);
if (influence != null && influence.Length > 0) {
builder.AppendFormat(", Influence: {0}",
influence.Select(x => x.InfluenceAmount).Sum()
);
}
return builder.ToString();

View File

@@ -13,6 +13,21 @@ public class MissionFailed : Transaction {
Failed = failed;
}
/// <summary>
/// Returns the amount of influence generated by failing this mission. The
/// system returns no influence for one INF missions, but sadly also for
/// when the influence had no affect at all (i.e. during a war).
/// </summary>
public long InfluenceAmount {
get {
if (Mission == null || string.IsNullOrEmpty(Mission.Influence)) {
return -1;
} else {
return Mission.Influence.Length * -1;
}
}
}
public override int CompareTo(Transaction? other) {
if (other == null || other.GetType() != typeof(MissionFailed)) {
return -1;

View File

@@ -0,0 +1,15 @@
using EDPlayerJournal.Entries;
namespace EDPlayerJournal.BGS.Parsers;
internal class ApproachSettlementParser : ITransactionParserPart {
public void Parse(Entry entry, TransactionParserContext context, TransactionParserOptions options, TransactionList transactions) {
ApproachSettlementEntry? approach = entry as ApproachSettlementEntry;
if (approach == null || string.IsNullOrEmpty(approach.Name)) {
return;
}
context.Settlement = approach.Name;
}
}

View File

@@ -298,20 +298,20 @@ internal class MissionCompletedParser : ITransactionParserPart {
if (context.CurrentSystemAddress == null) {
continue;
}
other.Value.Add(context.CurrentSystemAddress.Value, "");
other.Value.Add(context.CurrentSystemAddress.Value, new MissionInfluence());
// Mission gave no influence to the target faction, so we assume
// the target faction was in the same system.
} else if (string.Compare(source_faction_name, faction, true) == 0) {
// This happens if the source faction is not getting any influence
// This could be if the source faction is in a conflict, and thus does
// not gain any influence at all.
other.Value.Add(accepted_location.SystemAddress, "");
other.Value.Add(accepted_location.SystemAddress, new MissionInfluence());
// Just check if the target/source faction are the same, in which case
// we also have to make an additional entry
if (string.Compare(source_faction_name, target_faction_name, true) == 0 &&
context.CurrentSystemAddress != null) {
other.Value.Add(context.CurrentSystemAddress.Value, "");
other.Value.Add(context.CurrentSystemAddress.Value, new MissionInfluence());
}
}
}
@@ -663,6 +663,7 @@ internal class CommanderParser : ITransactionParserPart {
public class TransactionParser {
private static Dictionary<string, ITransactionParserPart> ParserParts { get; } = new()
{
{ Events.ApproachSettlement, new ApproachSettlementParser() },
{ Events.CapShipBond, new CapShipBondParser() },
{ Events.Commander, new CommanderParser() },
{ Events.CommitCrime, new CommitCrimeParser() },

View File

@@ -57,6 +57,11 @@ internal class TransactionParserContext {
public bool HaveSeenAlliedCorrespondent { get; set; } = false;
public bool HaveSeenEnemyCorrespondent { get; set; } = false;
/// <summary>
/// Current Odyssey settlement.
/// </summary>
public string? Settlement { get; set; } = null;
/// <summary>
/// Returns true if the current session is legacy
/// </summary>
@@ -115,6 +120,7 @@ internal class TransactionParserContext {
/// </summary>
public void LeftInstance() {
CurrentInstanceType = null;
Settlement = null;
}
public void DiscernCombatZone(TransactionList transactions, Entry e) {
@@ -223,6 +229,7 @@ internal class TransactionParserContext {
System = CurrentSystem,
Faction = faction,
IsLegacy = IsLegacy,
Settlement = Settlement,
Grade = grade,
Type = cztype,
// Sad truth is, if HaveSeenXXX is false, we just don't know for certain

View File

@@ -44,6 +44,6 @@ public class Credits {
return string.Format("{0:0.00}M", millions);
}
return "";
return string.Format("{0}", amount);
}
}

View File

@@ -0,0 +1,48 @@
namespace EDPlayerJournal.Entries;
public class ApproachSettlementEntry : Entry {
/// <summary>
/// Settlement name
/// </summary>
public string? Name { get; set; } = null;
/// <summary>
/// Market ID of the settlement
/// </summary>
public long? MarketID { get; set; } = null;
/// <summary>
/// System ID
/// </summary>
public long? SystemAddress { get; set; } = null;
/// <summary>
/// Body ID
/// </summary>
public long? BodyID { get; set; } = null;
/// <summary>
/// Name of the planet
/// </summary>
public string? BodyName { get; set; } = null;
/// <summary>
/// Planet latitude
/// </summary>
public double Latitude { get; set; } = 0.0;
/// <summary>
/// Planet longitude
/// </summary>
public double Longitude { get; set; } = 0.0;
protected override void Initialise() {
Name = JSON.Value<string?>("Name");
MarketID = JSON.Value<long?>("MarketID");
SystemAddress = JSON.Value<long?>("SystemID");
BodyID = JSON.Value<long?>("BodyID");
BodyName = JSON.Value<string?>("BodyName");
Longitude = JSON.Value<double?>("Longitude") ?? 0.0;
Latitude = JSON.Value<double?>("Latitude") ?? 0.0;
}
}

View File

@@ -12,6 +12,7 @@ namespace EDPlayerJournal.Entries;
/// </summary>
public class Entry {
private static readonly Dictionary<string, Type> classes = new Dictionary<string, Type> {
{ Events.ApproachSettlement, typeof(ApproachSettlementEntry) },
{ Events.Bounty, typeof(BountyEntry) },
{ Events.CapShipBond, typeof(CapShipBondEntry) },
{ Events.Commander, typeof(CommanderEntry) },
@@ -63,7 +64,15 @@ public class Entry {
public static Entry? Parse(string journalline) {
using (JsonReader reader = new JsonTextReader(new StringReader(journalline))) {
reader.DateParseHandling = DateParseHandling.None;
var json = JObject.Load(reader);
JObject? json = null;
try {
json = JObject.Load(reader);
} catch (Exception e) {
throw new InvalidJournalEntryException(
"invalid JSON journal entry: " + journalline,
e
);
}
if (json == null) {
return null;
}

View File

@@ -1,6 +1,7 @@
namespace EDPlayerJournal.Entries;
public class Events {
public static readonly string ApproachSettlement = "ApproachSettlement";
public static readonly string Bounty = "Bounty";
public static readonly string CapShipBond = "CapShipBond";
public static readonly string Commander = "Commander";

View File

@@ -6,6 +6,7 @@
public class InvalidJournalEntryException : Exception {
public InvalidJournalEntryException() { }
public InvalidJournalEntryException(string message) : base(message) { }
public InvalidJournalEntryException(string message, Exception inner) : base(message, inner) { }
}
/// <summary>

View File

@@ -17,6 +17,11 @@ public class JournalFile : IComparable<JournalFile>
private static Regex update11regex = new Regex("Journal\\.([^\\.]+)\\.(\\d+).log");
private static string iso8601 = "yyyyMMddTHHmmss";
/// <summary>
/// A public list of errors encountered while parsing the journal files
/// </summary>
public List<Exception> Errors { get; private set; } = new List<Exception>();
public static bool VerifyFile(string path) {
string filename = Path.GetFileName(path);
@@ -125,15 +130,20 @@ public class JournalFile : IComparable<JournalFile>
}
entries.Clear();
Errors.Clear();
foreach (var line in lines) {
// Skip empty lines
if (line.Trim().Length == 0) {
continue;
}
try {
Entry? entry = Entry.Parse(line);
if (entry != null) {
entries.Add(entry);
}
} catch (Exception ex) {
Errors.Add(ex);
}
}
}
}

View File

@@ -36,6 +36,31 @@ public class MissionInfluence {
/// </summary>
public string Influence { get; set; } = string.Empty;
public long InfluenceAmount {
get {
string trend = TrendAdjustedInfluence;
return (long)
(trend.Count(x => x == '-') * -1) +
trend.Count(x => x == '+')
;
}
}
/// <summary>
/// Returns how much influence was made, represented in pluses for positive influence,
/// and minuses with negative influence. This takes Trend (up, bad etc.) into account.
/// </summary>
public string TrendAdjustedInfluence {
get {
if (!string.IsNullOrEmpty(Trend) &&
Trend.Contains("bad", StringComparison.OrdinalIgnoreCase)) {
return new string('-', Influence.Length);
} else {
return new string('+', Influence.Length);
}
}
}
public static MissionInfluence FromJSON(JObject obj) {
MissionInfluence missionInfluence = new MissionInfluence();
@@ -394,27 +419,29 @@ public class Mission : IComparable<Mission> {
/// <param name="faction">Faction name in question.</param>
/// <param name="systemaddr">Star System address</param>
/// <returns>null if no entry was found, or a string denoting pluses for the amount influence gained.</returns>
public string? GetInfluenceForFaction(string faction, ulong systemaddr) {
public MissionInfluence[]? GetInfluenceForFaction(string faction, ulong systemaddr) {
var results = FactionEffects
.Where(x => string.Compare(x.Faction, faction) == 0)
.SelectMany(x => x.Influences)
.Where(x => (x.SystemAddress != null && x.SystemAddress == systemaddr))
.Select(x => x.Influence)
.Select(x => x)
.ToArray()
;
if (results == null || results.Length == 0) {
return null;
return new MissionInfluence[0];
}
return string.Join("", results);
return results;
}
/// <summary>
/// A convenient Dictionary containing all influences given out by faction,
/// then by system address and then by influence handed out.
/// then by system address and then by influence handed out. Influence can
/// be either a series of "+" for positive influence, or "-" for negative
/// influence.
/// </summary>
public Dictionary<string, Dictionary<ulong, string>> Influences {
public Dictionary<string, Dictionary<ulong, MissionInfluence>> Influences {
get {
return FactionEffects
.Where(x => x.Faction != null)
@@ -422,7 +449,10 @@ public class Mission : IComparable<Mission> {
x => (x.Faction ?? string.Empty),
x => x.Influences
.Where(x => x.SystemAddress != null)
.ToDictionary(x => (x.SystemAddress ?? 0), x => x.Influence)
.ToDictionary(
x => (x.SystemAddress ?? 0),
x => x
)
);
}
}

View File

@@ -22,6 +22,12 @@ public class PlayerJournal {
ScanFiles();
}
public List<Exception> AllErrors {
get {
return Files.SelectMany(x => x.Errors).ToList();
}
}
public List<JournalFile> Files {
get { return journalfiles; }
}

View File

@@ -8,11 +8,16 @@ public enum ThargoidVessel {
Basilisk = 4,
Medusa = 5,
Hydra = 6,
Glaive = 7,
// Includes Glaive and Scythe
Hunter = 7,
/// <summary>
/// Thargoid drone
/// </summary>
Revenant = 8,
/// <summary>
/// New thargoid drone in U17
/// </summary>
Banshee = 9,
}
public class Thargoid {
@@ -23,8 +28,10 @@ public class Thargoid {
{ 25000, ThargoidVessel.Revenant },
{ 65000, ThargoidVessel.Scout },
{ 75000, ThargoidVessel.Scout },
// New in Update 17
{ 100000, ThargoidVessel.Banshee },
// New in Update 15
{ 4500000, ThargoidVessel.Glaive },
{ 4500000, ThargoidVessel.Hunter },
{ 6500000, ThargoidVessel.Cyclops },
{ 20000000, ThargoidVessel.Basilisk },
//{ 25000000, ThargoidVessel.Orthrus },
@@ -46,7 +53,7 @@ public class Thargoid {
};
public static Dictionary<ThargoidVessel, string?> VesselNames { get; } = new() {
{ ThargoidVessel.Unknown, null },
{ ThargoidVessel.Unknown, "(Unknown)" },
{ ThargoidVessel.Revenant, "Revenant" },
{ ThargoidVessel.Scout, "Scout" },
{ ThargoidVessel.Orthrus, "Orthrus" },
@@ -54,7 +61,8 @@ public class Thargoid {
{ ThargoidVessel.Basilisk, "Basilisk" },
{ ThargoidVessel.Medusa, "Medusa" },
{ ThargoidVessel.Hydra, "Hydra" },
{ ThargoidVessel.Glaive, "Glaive" },
{ ThargoidVessel.Hunter, "Hunter" },
{ ThargoidVessel.Banshee, "Banshee" },
};
public static ThargoidVessel GetVesselByPayout(ulong payout) {

View File

@@ -59,9 +59,9 @@ public class MissionTest {
Assert.IsTrue(e.IsEmptyFaction);
Assert.AreEqual(e.Faction, string.Empty);
string? influence = m.GetInfluenceForFaction("", 251012319587UL);
var influence = m.GetInfluenceForFaction("", 251012319587UL);
Assert.IsNotNull(influence);
Assert.AreEqual(influence, "+");
Assert.AreEqual(influence[0].Influence, "+");
e = m.FactionEffects[1];
Assert.AreEqual(e.Faction, "Social LHS 6103 Confederation");
@@ -101,22 +101,25 @@ public class MissionTest {
Assert.AreEqual(effect.Reputation, "++");
string? influence;
influence = m.GetInfluenceForFaction("Salus Imperial Society", 1865919973739UL);
Assert.AreEqual(influence, "++");
var influence = m.GetInfluenceForFaction("Salus Imperial Society", 1865919973739UL);
Assert.IsNotNull(influence);
Assert.IsTrue(influence.Length > 0);
Assert.AreEqual(influence[0].Influence, "++");
influence = m.GetInfluenceForFaction("Salus Imperial Society", 1733186884306UL);
Assert.AreEqual(influence, "++");
Assert.IsNotNull(influence);
Assert.IsTrue(influence.Length > 0);
Assert.AreEqual(influence[0].Influence, "++");
influence = m.GetInfluenceForFaction("Saelishi Saxons", 1733186884306UL);
Assert.IsNull(influence);
Assert.IsNotNull(influence);
Assert.AreEqual(influence.Length, 0);
// Only one entry are we only have Salus
Assert.AreEqual(m.Influences.Count, 1);
Assert.AreEqual(m.Influences["Salus Imperial Society"].Count, 2);
Assert.AreEqual(m.Influences["Salus Imperial Society"][1865919973739UL], "++");
Assert.AreEqual(m.Influences["Salus Imperial Society"][1733186884306UL], "++");
Assert.AreEqual(m.Influences["Salus Imperial Society"][1865919973739UL].Influence, "++");
Assert.AreEqual(m.Influences["Salus Imperial Society"][1733186884306UL].Influence, "++");
}
[TestMethod]

View File

@@ -19,7 +19,13 @@ public class TestTransactionParser {
return;
}
List<Transaction>? transactions = parser.Parse(entries);
var options = new TransactionParserOptions() {
IgnoreInfluenceSupport = false,
IgnoreExoBiology = false,
IgnoreFleetCarrierFaction = false,
IgnoreMarketBuy = false,
};
List<Transaction>? transactions = parser.Parse(entries, options);
Assert.IsNotNull(transactions, "could not parse entries");
Assert.AreEqual(transactions.Count, 3);
@@ -144,7 +150,14 @@ public class TestTransactionParser {
return;
}
List<Transaction>? transactions = parser.Parse(entries);
var options = new TransactionParserOptions() {
IgnoreInfluenceSupport = false,
IgnoreExoBiology = false,
IgnoreFleetCarrierFaction = false,
IgnoreMarketBuy = false,
};
List<Transaction>? transactions = parser.Parse(entries, options);
Assert.IsNotNull(transactions, "could not parse entries");
Assert.AreEqual(transactions.Count, 1);
Assert.IsInstanceOfType(transactions[0], typeof(OrganicData), "result is not of type Organic Data");

View File

@@ -22,14 +22,17 @@ public class ThargoidKills {
Assert.IsNotNull(transactions, "could not parse entries");
Assert.AreEqual(transactions.Count, 3);
// In recent updates the payout was changed, that's why this test reports unknown thargoid vessels
// This test makes sure the new parser does not conflict with legacy values
//
Assert.IsInstanceOfType(transactions[0], typeof(ThargoidKill), "result is not of type ThargoidKill");
Assert.AreEqual(transactions[0].ThargoidType, EDPlayerJournal.ThargoidVessel.Scout);
Assert.AreEqual(transactions[0].ThargoidType, EDPlayerJournal.ThargoidVessel.Unknown);
Assert.IsInstanceOfType(transactions[1], typeof(ThargoidKill), "result is not of type ThargoidKill");
Assert.AreEqual(transactions[1].ThargoidType, EDPlayerJournal.ThargoidVessel.Basilisk);
Assert.AreEqual(transactions[1].ThargoidType, EDPlayerJournal.ThargoidVessel.Unknown);
Assert.IsInstanceOfType(transactions[2], typeof(ThargoidKill), "result is not of type ThargoidKill");
Assert.AreEqual(transactions[2].ThargoidType, EDPlayerJournal.ThargoidVessel.Scout);
Assert.AreEqual(transactions[2].ThargoidType, EDPlayerJournal.ThargoidVessel.Unknown);
}
[TestMethod]

View File

@@ -4,14 +4,12 @@ using System.Collections.Generic;
using System.Text;
using EliteBGS.LogGenerator;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace EliteBGS;
public class DiscordLogGenerator {
protected List<LogFormatter> formatters = new List<LogFormatter>() {
new MissionFormat(),
new FailedMissionFormat(),
new MurderFormat(),
new VoucherFormat(),
new ThargoidFormatter(),

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework>
<OutputType>WinExe</OutputType>
<Version>0.3.4</Version>
<Version>0.3.6</Version>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>

View File

@@ -10,7 +10,7 @@ class CombatZoneFormat : LogFormatter {
var logs = objective
.EnabledOfType<CombatZone>()
.OrderBy(x => (CombatZones.DifficultyRank(x.Grade) ?? 0))
.GroupBy(x => new { x.Type, x.Grade })
.GroupBy(x => new { x.Type, x.Grade, x.Settlement })
.ToDictionary(x => x.Key, x => x.ToList())
;
StringBuilder builder = new StringBuilder();
@@ -23,6 +23,11 @@ class CombatZoneFormat : LogFormatter {
int optionals = log.Value
.Sum(x => x.OptionalObjectivesCompleted)
;
var settlements = log.Value
.Select(x => x.Settlement)
.Distinct()
;
string settl = string.Join(", ", settlements);
if (!string.IsNullOrEmpty(log.Key.Grade)) {
builder.AppendFormat("Won {0}x {1} {2} Combat Zone(s)",
log.Value.Count,
@@ -39,6 +44,9 @@ class CombatZoneFormat : LogFormatter {
if (optionals > 0) {
builder.AppendFormat(" (with {0} optional objectives)", optionals);
}
if (!string.IsNullOrEmpty(settl)) {
builder.AppendFormat(" (at {0})", settl);
}
builder.Append("\n");
}

View File

@@ -1,60 +0,0 @@
using System.Linq;
using System.Text;
using EDPlayerJournal.BGS;
namespace EliteBGS.LogGenerator;
public class FailedMissionFormat : LogFormatter {
public string GenerateLog(Objective objective) {
var missions = objective.EnabledOfType<MissionFailed>();
if (missions.Count <= 0) {
return "";
}
StringBuilder builder = new StringBuilder();
var grouping = missions
.GroupBy(x => x.Mission.IsOnFoot)
;
foreach (var group in grouping) {
int amount = group.Count();
if (group.Key) {
builder.AppendFormat("Failed {0} On Foot Mission(s)\n", amount);
} else {
builder.AppendFormat("Failed {0} Ship Mission(s)\n", amount);
}
}
return builder.ToString().Trim();
}
public string GenerateSummary(Objective objective) {
var missions = objective.EnabledOfType<MissionFailed>();
if (missions.Count <= 0) {
return "";
}
StringBuilder sb = new();
int onFootFails = missions.Where(x => x.Mission.IsOnFoot).Count();
int shipFails = missions.Where(x => !x.Mission.IsOnFoot).Count();
sb.Append("Fails: ");
if (onFootFails > 0) {
sb.AppendFormat("{0} Ground", onFootFails);
}
if (shipFails > 0) {
if (onFootFails > 0) {
sb.Append(", ");
}
sb.AppendFormat("{0} Ship", shipFails);
}
return sb.ToString();
}
}

View File

@@ -6,17 +6,72 @@ using EDPlayerJournal.BGS;
namespace EliteBGS.LogGenerator;
public class MissionFormat : LogFormatter {
private string GenerateFailedLog(Objective objective) {
var missions = objective.EnabledOfType<MissionFailed>();
if (missions.Count <= 0) {
return "";
}
StringBuilder builder = new StringBuilder();
var grouping = missions
.GroupBy(x => x.Mission.IsOnFoot)
;
foreach (var group in grouping) {
int amount = group.Count();
if (group.Key) {
builder.AppendFormat("Failed {0} On Foot Mission(s)\n", amount);
} else {
builder.AppendFormat("Failed {0} Ship Mission(s)\n", amount);
}
}
return builder.ToString().Trim();
}
private string GenerateFailedSummary(Objective objective) {
var missions = objective.EnabledOfType<MissionFailed>();
if (missions.Count <= 0) {
return "";
}
StringBuilder sb = new();
int onFootFails = missions.Where(x => x.Mission.IsOnFoot).Count();
int shipFails = missions.Where(x => !x.Mission.IsOnFoot).Count();
sb.Append("Fails: ");
if (onFootFails > 0) {
sb.AppendFormat("{0} Ground", onFootFails);
}
if (shipFails > 0) {
if (onFootFails > 0) {
sb.Append(", ");
}
sb.AppendFormat("{0} Ship", shipFails);
}
return sb.ToString();
}
public string GenerateLog(Objective objective) {
Dictionary<string, Dictionary<string, int>> collated = new();
Dictionary<string, ulong> passengers = new();
StringBuilder output = new StringBuilder();
int total_influence = 0;
long total_influence = 0;
var missions = objective.EnabledOfType<MissionCompleted>();
var support = objective.EnabledOfType<InfluenceSupport>();
var failed = objective.EnabledOfType<MissionFailed>();
if ((missions == null || missions.Count == 0) &&
(support == null || support.Count == 0)) {
(support == null || support.Count == 0) &&
(failed == null || failed.Count == 0)) {
return "";
}
@@ -60,17 +115,25 @@ public class MissionFormat : LogFormatter {
output.Append("\n");
// Handle failed missions, and add them to the log and influence tally
string failedlog = GenerateFailedLog(objective);
if (!string.IsNullOrEmpty(failedlog)) {
output.Append(failedlog);
output.Append("\n");
}
total_influence += failed.Sum(x => x.InfluenceAmount);
foreach (InfluenceSupport inf in support) {
output.Append(inf.ToString());
output.Append("\n");
total_influence += inf.Influence.Length;
total_influence += inf.Influence.InfluenceAmount;
}
if (support.Count() > 0) {
output.Append("\n");
}
if (total_influence > 0) {
if (total_influence != 0) {
output.AppendFormat("Total Influence: {0}", total_influence);
}
@@ -84,13 +147,24 @@ public class MissionFormat : LogFormatter {
;
long support = objective
.EnabledOfType<InfluenceSupport>()
.Sum(x => x.Influence.Length)
.Sum(x => x.Influence.InfluenceAmount)
;
long failed = objective
.EnabledOfType<MissionFailed>()
.Sum(x => x.InfluenceAmount)
;
if (influence + support <= 0) {
if (influence == 0 && support == 0 && failed == 0) {
return "";
}
return string.Format("INF: {0}", influence + support);
string failedsummary = GenerateFailedSummary(objective);
string summary = string.Format("INF: {0}", influence + support + failed);
if (!string.IsNullOrEmpty(failedsummary)) {
string.Join("; ", summary, failedsummary);
}
return summary;
}
}

View File

@@ -233,6 +233,12 @@ public partial class MainWindow : MetroWindow {
HandleEntries(entries, start, end);
GenerateLog();
var errors = journal.AllErrors;
foreach (var error in errors) {
Log("An error has occured in the Journal file, please send this to CMDR Hekateh:");
Log(error.ToString());
}
} catch (Exception exception) {
Log("Something went terribly wrong while parsing the E:D player journal.");
Log("Please send this to CMDR Hekateh:");

View File

@@ -1,6 +1,4 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
@@ -51,5 +49,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.3.4.0")]
[assembly: AssemblyFileVersion("0.3.4.0")]
[assembly: AssemblyVersion("0.3.6.0")]
[assembly: AssemblyFileVersion("0.3.6.0")]

View File

@@ -1,5 +1,23 @@
# EliteBGS changelog
# 0.3.6 on 25.10.2023
* U17 introduced invalid JSON into the player journal. EliteBGS can now skip over
those and keep processing. This way players won't have to delete lines in their
journals anymore to keep using the tool.
* Banshee has been added.
## 0.3.5 on 11.09.2023
* Small bounty voucher formats are no longer suppressed.
* Glaive has been renamed to "Hunter" since Scythe has the same bounty
and they cannot be distinguished.
* Mission influence can now also be negative. Failed missions now properly
report the amount of negative influence given to a faction.
* Mission secondary influences now also support negative influences. This
for example happens if you take a mission to murder another faction's
civlians, which causes negative INF.
## 0.3.4 on 18.06.2023
* Added possibility to specify allied, as well as enemy captain and correspondent.

View File

@@ -75,7 +75,7 @@ tab. With update 15, this behaviour should be fixed.
The player journal only tells the faction that issued the bounty upon murder, and
not the faction of the NPC killed. The tool has to fetch that from you scanning the
hip. If you didn't fully scan the ship before murdering it, the tool won't know
ship. If you didn't fully scan the ship before murdering it, the tool won't know
the faction of the NPC.
### Why does cartography data, and sold cargo show up for the wrong faction, but for the right station/system?

View File

@@ -20,13 +20,13 @@ command line:
winget install Microsoft.DotNet.DesktopRuntime.7
```
You can download the **latest** version **0.3.4** at CodeBerg:
You can download the **latest** version **0.3.6** at CodeBerg:
* [https://codeberg.org/nola/EDBGS/releases](https://codeberg.org/nola/EDBGS/releases)
Or alternatively from my server:
* [https://bgs.n0la.org/elitebgs-0.3.4.zip](https://bgs.n0la.org/elitebgs-0.3.4.zip)
* [https://bgs.n0la.org/elitebgs-0.3.6.zip](https://bgs.n0la.org/elitebgs-0.3.6.zip)
## Old Versions