Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 450824733d | |||
| 110f909c6f | |||
| a1099628a0 | |||
| 7e85159fd5 | |||
| 2e8daca61c | |||
| 05b714a607 | |||
| 3b0492c70f | |||
| c20280eb13 | |||
| dd863c326e | |||
| 2012aab7b3 | |||
| abb7954614 | |||
| 0f44a6a9a7 | |||
| 34e0a0c8ba | |||
| b0b82811cc | |||
| 4855d78823 | |||
| 5ea288ee86 | |||
| f3fc99a3f3 | |||
| 2bee03dbc2 | |||
| 16b579688d | |||
| 9994a45d06 | |||
| d6e2280a00 | |||
| 160f4f8370 | |||
| 4400418d30 | |||
| 43037b0a5b | |||
| afc831cf31 | |||
| 4ab54ee576 | |||
| d6842115c5 | |||
| acb60e0a08 | |||
| dac9b7b8c7 | |||
| 3338f573c8 | |||
| 204d6b8914 | |||
| 4c75515a70 | |||
| c43c6f742a | |||
| c7a70598c4 | |||
| cdd7eb33de | |||
| dab39b9a4e |
@@ -43,6 +43,12 @@ public class CombatZone : Transaction {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool? CapitalShip { get; set; }
|
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>
|
/// <summary>
|
||||||
/// How many optional objectives were completed?
|
/// How many optional objectives were completed?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace EDPlayerJournal.BGS;
|
|||||||
/// faction to another. Both sometimes gain influence.
|
/// faction to another. Both sometimes gain influence.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class InfluenceSupport : Transaction {
|
public class InfluenceSupport : Transaction {
|
||||||
public string Influence { get; set; } = "";
|
public MissionInfluence? Influence { get; set; } = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Relevant mission completed entry
|
/// Relevant mission completed entry
|
||||||
@@ -46,7 +46,7 @@ public class InfluenceSupport : Transaction {
|
|||||||
|
|
||||||
builder.AppendFormat("Influence gained from \"{0}\": \"{1}\"",
|
builder.AppendFormat("Influence gained from \"{0}\": \"{1}\"",
|
||||||
missionname,
|
missionname,
|
||||||
string.IsNullOrEmpty(Influence) ? "NONE" : Influence
|
Influence == null ? "NONE" : Influence.TrendAdjustedInfluence
|
||||||
);
|
);
|
||||||
|
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
|
|||||||
@@ -38,7 +38,14 @@ public class MissionCompleted : Transaction {
|
|||||||
return "";
|
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);
|
var influence = CompletedEntry.Mission.GetInfluenceForFaction(Faction, SystemAddress);
|
||||||
|
|
||||||
builder.AppendFormat("{0}", MissionName);
|
builder.AppendFormat("{0}", MissionName);
|
||||||
if (influence != "") {
|
if (influence != null && influence.Length > 0) {
|
||||||
builder.AppendFormat(", Influence: {0}", influence);
|
builder.AppendFormat(", Influence: {0}",
|
||||||
|
influence.Select(x => x.InfluenceAmount).Sum()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
|
|||||||
@@ -13,6 +13,21 @@ public class MissionFailed : Transaction {
|
|||||||
Failed = failed;
|
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) {
|
public override int CompareTo(Transaction? other) {
|
||||||
if (other == null || other.GetType() != typeof(MissionFailed)) {
|
if (other == null || other.GetType() != typeof(MissionFailed)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
15
EDPlayerJournal/BGS/Parsers/ApproachSettlementParser.cs
Normal file
15
EDPlayerJournal/BGS/Parsers/ApproachSettlementParser.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
30
EDPlayerJournal/BGS/Parsers/CarrierJumpParser.cs
Normal file
30
EDPlayerJournal/BGS/Parsers/CarrierJumpParser.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using EDPlayerJournal.Entries;
|
||||||
|
|
||||||
|
namespace EDPlayerJournal.BGS.Parsers;
|
||||||
|
|
||||||
|
internal class CarrierJumpParser : ITransactionParserPart {
|
||||||
|
public void Parse(Entry entry, TransactionParserContext context, TransactionParserOptions options, TransactionList transactions) {
|
||||||
|
CarrierJump? jump = entry as CarrierJump;
|
||||||
|
|
||||||
|
if (jump == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!jump.Docked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.CurrentSystem = jump.StarSystem;
|
||||||
|
context.CurrentSystemAddress = jump.SystemAddress;
|
||||||
|
|
||||||
|
context.SystemsByID.TryAdd(jump.SystemAddress, jump.StarSystem);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(jump.SystemFaction)) {
|
||||||
|
context.ControllingFaction = jump.SystemFaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jump.SystemFactions != null && jump.SystemFactions.Count > 0) {
|
||||||
|
context.SystemFactions[jump.StarSystem] = jump.SystemFactions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
EDPlayerJournal/BGS/Parsers/MusicParser.cs
Normal file
17
EDPlayerJournal/BGS/Parsers/MusicParser.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using EDPlayerJournal.Entries;
|
||||||
|
|
||||||
|
namespace EDPlayerJournal.BGS.Parsers;
|
||||||
|
|
||||||
|
internal class MusicParser : ITransactionParserPart {
|
||||||
|
public void Parse(Entry entry, TransactionParserContext context, TransactionParserOptions options, TransactionList transactions) {
|
||||||
|
MusicEntry? entryMusic = (MusicEntry)entry;
|
||||||
|
|
||||||
|
if (entryMusic == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Compare(entryMusic.MusicTrack, "Combat_CapitalShip") == 0) {
|
||||||
|
context.HaveSeenCapShip = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -298,20 +298,20 @@ internal class MissionCompletedParser : ITransactionParserPart {
|
|||||||
if (context.CurrentSystemAddress == null) {
|
if (context.CurrentSystemAddress == null) {
|
||||||
continue;
|
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
|
// Mission gave no influence to the target faction, so we assume
|
||||||
// the target faction was in the same system.
|
// the target faction was in the same system.
|
||||||
} else if (string.Compare(source_faction_name, faction, true) == 0) {
|
} else if (string.Compare(source_faction_name, faction, true) == 0) {
|
||||||
// This happens if the source faction is not getting any influence
|
// 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
|
// This could be if the source faction is in a conflict, and thus does
|
||||||
// not gain any influence at all.
|
// 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
|
// Just check if the target/source faction are the same, in which case
|
||||||
// we also have to make an additional entry
|
// we also have to make an additional entry
|
||||||
if (string.Compare(source_faction_name, target_faction_name, true) == 0 &&
|
if (string.Compare(source_faction_name, target_faction_name, true) == 0 &&
|
||||||
context.CurrentSystemAddress != null) {
|
context.CurrentSystemAddress != null) {
|
||||||
other.Value.Add(context.CurrentSystemAddress.Value, "");
|
other.Value.Add(context.CurrentSystemAddress.Value, new MissionInfluence());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -663,7 +663,9 @@ internal class CommanderParser : ITransactionParserPart {
|
|||||||
public class TransactionParser {
|
public class TransactionParser {
|
||||||
private static Dictionary<string, ITransactionParserPart> ParserParts { get; } = new()
|
private static Dictionary<string, ITransactionParserPart> ParserParts { get; } = new()
|
||||||
{
|
{
|
||||||
|
{ Events.ApproachSettlement, new ApproachSettlementParser() },
|
||||||
{ Events.CapShipBond, new CapShipBondParser() },
|
{ Events.CapShipBond, new CapShipBondParser() },
|
||||||
|
{ Events.CarrierJump, new CarrierJumpParser() },
|
||||||
{ Events.Commander, new CommanderParser() },
|
{ Events.Commander, new CommanderParser() },
|
||||||
{ Events.CommitCrime, new CommitCrimeParser() },
|
{ Events.CommitCrime, new CommitCrimeParser() },
|
||||||
{ Events.Died, new DiedParser() },
|
{ Events.Died, new DiedParser() },
|
||||||
@@ -682,6 +684,7 @@ public class TransactionParser {
|
|||||||
{ Events.MissionFailed, new MissionFailedParser() },
|
{ Events.MissionFailed, new MissionFailedParser() },
|
||||||
{ Events.Missions, new MissionsParser() },
|
{ Events.Missions, new MissionsParser() },
|
||||||
{ Events.MultiSellExplorationData, new MultiSellExplorationDataParser() },
|
{ Events.MultiSellExplorationData, new MultiSellExplorationDataParser() },
|
||||||
|
{ Events.Music, new MusicParser() },
|
||||||
{ Events.ReceiveText, new ReceiveTextParser() },
|
{ Events.ReceiveText, new ReceiveTextParser() },
|
||||||
{ Events.RedeemVoucher, new RedeemVoucherParser() },
|
{ Events.RedeemVoucher, new RedeemVoucherParser() },
|
||||||
{ Events.SearchAndRescue, new SearchAndRescueParser() },
|
{ Events.SearchAndRescue, new SearchAndRescueParser() },
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ internal class TransactionParserContext {
|
|||||||
public bool HaveSeenAlliedCorrespondent { get; set; } = false;
|
public bool HaveSeenAlliedCorrespondent { get; set; } = false;
|
||||||
public bool HaveSeenEnemyCorrespondent { get; set; } = false;
|
public bool HaveSeenEnemyCorrespondent { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Current Odyssey settlement.
|
||||||
|
/// </summary>
|
||||||
|
public string? Settlement { get; set; } = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the current session is legacy
|
/// Returns true if the current session is legacy
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -115,6 +120,7 @@ internal class TransactionParserContext {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void LeftInstance() {
|
public void LeftInstance() {
|
||||||
CurrentInstanceType = null;
|
CurrentInstanceType = null;
|
||||||
|
Settlement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DiscernCombatZone(TransactionList transactions, Entry e) {
|
public void DiscernCombatZone(TransactionList transactions, Entry e) {
|
||||||
@@ -223,6 +229,7 @@ internal class TransactionParserContext {
|
|||||||
System = CurrentSystem,
|
System = CurrentSystem,
|
||||||
Faction = faction,
|
Faction = faction,
|
||||||
IsLegacy = IsLegacy,
|
IsLegacy = IsLegacy,
|
||||||
|
Settlement = Settlement,
|
||||||
Grade = grade,
|
Grade = grade,
|
||||||
Type = cztype,
|
Type = cztype,
|
||||||
// Sad truth is, if HaveSeenXXX is false, we just don't know for certain
|
// Sad truth is, if HaveSeenXXX is false, we just don't know for certain
|
||||||
|
|||||||
@@ -44,6 +44,6 @@ public class Credits {
|
|||||||
return string.Format("{0:0.00}M", millions);
|
return string.Format("{0:0.00}M", millions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return string.Format("{0}", amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
48
EDPlayerJournal/Entries/ApproachSettlementEntry.cs
Normal file
48
EDPlayerJournal/Entries/ApproachSettlementEntry.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
44
EDPlayerJournal/Entries/CarrierJump.cs
Normal file
44
EDPlayerJournal/Entries/CarrierJump.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace EDPlayerJournal.Entries;
|
||||||
|
|
||||||
|
public class CarrierJump : Entry {
|
||||||
|
public bool Docked { get; set; } = false;
|
||||||
|
|
||||||
|
public string? StationName { get; set; } = null;
|
||||||
|
|
||||||
|
public string? StationType { get; set; } = null;
|
||||||
|
|
||||||
|
public string? StarSystem { get; set; } = null;
|
||||||
|
|
||||||
|
public ulong SystemAddress { get; set; } = 0;
|
||||||
|
|
||||||
|
public string? SystemFaction { get; set; } = null;
|
||||||
|
|
||||||
|
public List<Faction> SystemFactions { get; set; } = new List<Faction>();
|
||||||
|
|
||||||
|
protected override void Initialise() {
|
||||||
|
Docked = JSON.Value<bool?>("Docked") ?? false;
|
||||||
|
|
||||||
|
StarSystem = JSON.Value<string>("StarSystem");
|
||||||
|
SystemAddress = JSON.Value<ulong?>("SystemAddress") ?? 0;
|
||||||
|
|
||||||
|
StationName = JSON.Value<string?>("StationName");
|
||||||
|
StationType = JSON.Value<string?>("StationType");
|
||||||
|
|
||||||
|
var faction = JSON.Value<JObject>("SystemFaction");
|
||||||
|
if (faction != null) {
|
||||||
|
SystemFaction = faction.Value<string>("Name");
|
||||||
|
}
|
||||||
|
|
||||||
|
var factions = JSON.Value<JArray>("Factions");
|
||||||
|
if (factions != null) {
|
||||||
|
foreach (JObject system_faction in factions) {
|
||||||
|
Faction? f = Faction.FromJSON(system_faction);
|
||||||
|
if (f != null) {
|
||||||
|
SystemFactions.Add(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,8 +12,10 @@ namespace EDPlayerJournal.Entries;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class Entry {
|
public class Entry {
|
||||||
private static readonly Dictionary<string, Type> classes = new Dictionary<string, Type> {
|
private static readonly Dictionary<string, Type> classes = new Dictionary<string, Type> {
|
||||||
|
{ Events.ApproachSettlement, typeof(ApproachSettlementEntry) },
|
||||||
{ Events.Bounty, typeof(BountyEntry) },
|
{ Events.Bounty, typeof(BountyEntry) },
|
||||||
{ Events.CapShipBond, typeof(CapShipBondEntry) },
|
{ Events.CapShipBond, typeof(CapShipBondEntry) },
|
||||||
|
{ Events.CarrierJump, typeof(CarrierJump) },
|
||||||
{ Events.Commander, typeof(CommanderEntry) },
|
{ Events.Commander, typeof(CommanderEntry) },
|
||||||
{ Events.CommitCrime, typeof(CommitCrimeEntry) },
|
{ Events.CommitCrime, typeof(CommitCrimeEntry) },
|
||||||
{ Events.Died, typeof(DiedEntry) },
|
{ Events.Died, typeof(DiedEntry) },
|
||||||
@@ -36,6 +38,7 @@ public class Entry {
|
|||||||
{ Events.MissionRedirected, typeof(MissionRedirectedEntry) },
|
{ Events.MissionRedirected, typeof(MissionRedirectedEntry) },
|
||||||
{ Events.Missions, typeof(MissionsEntry) },
|
{ Events.Missions, typeof(MissionsEntry) },
|
||||||
{ Events.MultiSellExplorationData, typeof(MultiSellExplorationDataEntry) },
|
{ Events.MultiSellExplorationData, typeof(MultiSellExplorationDataEntry) },
|
||||||
|
{ Events.Music, typeof(MusicEntry) },
|
||||||
{ Events.ReceiveText, typeof(ReceiveTextEntry) },
|
{ Events.ReceiveText, typeof(ReceiveTextEntry) },
|
||||||
{ Events.RedeemVoucher, typeof(RedeemVoucherEntry) },
|
{ Events.RedeemVoucher, typeof(RedeemVoucherEntry) },
|
||||||
{ Events.SearchAndRescue, typeof(SearchAndRescueEntry) },
|
{ Events.SearchAndRescue, typeof(SearchAndRescueEntry) },
|
||||||
@@ -63,7 +66,15 @@ public class Entry {
|
|||||||
public static Entry? Parse(string journalline) {
|
public static Entry? Parse(string journalline) {
|
||||||
using (JsonReader reader = new JsonTextReader(new StringReader(journalline))) {
|
using (JsonReader reader = new JsonTextReader(new StringReader(journalline))) {
|
||||||
reader.DateParseHandling = DateParseHandling.None;
|
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) {
|
if (json == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
namespace EDPlayerJournal.Entries;
|
namespace EDPlayerJournal.Entries;
|
||||||
|
|
||||||
public class Events {
|
public class Events {
|
||||||
|
public static readonly string ApproachSettlement = "ApproachSettlement";
|
||||||
public static readonly string Bounty = "Bounty";
|
public static readonly string Bounty = "Bounty";
|
||||||
public static readonly string CapShipBond = "CapShipBond";
|
public static readonly string CapShipBond = "CapShipBond";
|
||||||
|
public static readonly string CarrierJump = "CarrierJump";
|
||||||
public static readonly string Commander = "Commander";
|
public static readonly string Commander = "Commander";
|
||||||
public static readonly string CommitCrime = "CommitCrime";
|
public static readonly string CommitCrime = "CommitCrime";
|
||||||
public static readonly string Died = "Died";
|
public static readonly string Died = "Died";
|
||||||
@@ -26,6 +28,7 @@ public class Events {
|
|||||||
public static readonly string MissionRedirected = "MissionRedirected";
|
public static readonly string MissionRedirected = "MissionRedirected";
|
||||||
public static readonly string Missions = "Missions";
|
public static readonly string Missions = "Missions";
|
||||||
public static readonly string MultiSellExplorationData = "MultiSellExplorationData";
|
public static readonly string MultiSellExplorationData = "MultiSellExplorationData";
|
||||||
|
public static readonly string Music = "Music";
|
||||||
public static readonly string ReceiveText = "ReceiveText";
|
public static readonly string ReceiveText = "ReceiveText";
|
||||||
public static readonly string RedeemVoucher = "RedeemVoucher";
|
public static readonly string RedeemVoucher = "RedeemVoucher";
|
||||||
public static readonly string SearchAndRescue = "SearchAndRescue";
|
public static readonly string SearchAndRescue = "SearchAndRescue";
|
||||||
|
|||||||
9
EDPlayerJournal/Entries/MusicEntry.cs
Normal file
9
EDPlayerJournal/Entries/MusicEntry.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace EDPlayerJournal.Entries;
|
||||||
|
|
||||||
|
public class MusicEntry : Entry {
|
||||||
|
public string? MusicTrack { get; set; } = null;
|
||||||
|
|
||||||
|
protected override void Initialise() {
|
||||||
|
MusicTrack = JSON.Value<string?>("MusicTrack");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
public class InvalidJournalEntryException : Exception {
|
public class InvalidJournalEntryException : Exception {
|
||||||
public InvalidJournalEntryException() { }
|
public InvalidJournalEntryException() { }
|
||||||
public InvalidJournalEntryException(string message) : base(message) { }
|
public InvalidJournalEntryException(string message) : base(message) { }
|
||||||
|
public InvalidJournalEntryException(string message, Exception inner) : base(message, inner) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ public class JournalFile : IComparable<JournalFile>
|
|||||||
private static Regex update11regex = new Regex("Journal\\.([^\\.]+)\\.(\\d+).log");
|
private static Regex update11regex = new Regex("Journal\\.([^\\.]+)\\.(\\d+).log");
|
||||||
private static string iso8601 = "yyyyMMddTHHmmss";
|
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) {
|
public static bool VerifyFile(string path) {
|
||||||
string filename = Path.GetFileName(path);
|
string filename = Path.GetFileName(path);
|
||||||
|
|
||||||
@@ -125,15 +130,20 @@ public class JournalFile : IComparable<JournalFile>
|
|||||||
}
|
}
|
||||||
|
|
||||||
entries.Clear();
|
entries.Clear();
|
||||||
|
Errors.Clear();
|
||||||
foreach (var line in lines) {
|
foreach (var line in lines) {
|
||||||
// Skip empty lines
|
// Skip empty lines
|
||||||
if (line.Trim().Length == 0) {
|
if (line.Trim().Length == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
Entry? entry = Entry.Parse(line);
|
Entry? entry = Entry.Parse(line);
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
entries.Add(entry);
|
entries.Add(entry);
|
||||||
}
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Errors.Add(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,31 @@ public class MissionInfluence {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Influence { get; set; } = string.Empty;
|
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) {
|
public static MissionInfluence FromJSON(JObject obj) {
|
||||||
MissionInfluence missionInfluence = new MissionInfluence();
|
MissionInfluence missionInfluence = new MissionInfluence();
|
||||||
|
|
||||||
@@ -394,27 +419,29 @@ public class Mission : IComparable<Mission> {
|
|||||||
/// <param name="faction">Faction name in question.</param>
|
/// <param name="faction">Faction name in question.</param>
|
||||||
/// <param name="systemaddr">Star System address</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>
|
/// <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
|
var results = FactionEffects
|
||||||
.Where(x => string.Compare(x.Faction, faction) == 0)
|
.Where(x => string.Compare(x.Faction, faction) == 0)
|
||||||
.SelectMany(x => x.Influences)
|
.SelectMany(x => x.Influences)
|
||||||
.Where(x => (x.SystemAddress != null && x.SystemAddress == systemaddr))
|
.Where(x => (x.SystemAddress != null && x.SystemAddress == systemaddr))
|
||||||
.Select(x => x.Influence)
|
.Select(x => x)
|
||||||
.ToArray()
|
.ToArray()
|
||||||
;
|
;
|
||||||
|
|
||||||
if (results == null || results.Length == 0) {
|
if (results == null || results.Length == 0) {
|
||||||
return null;
|
return new MissionInfluence[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Join("", results);
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A convenient Dictionary containing all influences given out by faction,
|
/// 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>
|
/// </summary>
|
||||||
public Dictionary<string, Dictionary<ulong, string>> Influences {
|
public Dictionary<string, Dictionary<ulong, MissionInfluence>> Influences {
|
||||||
get {
|
get {
|
||||||
return FactionEffects
|
return FactionEffects
|
||||||
.Where(x => x.Faction != null)
|
.Where(x => x.Faction != null)
|
||||||
@@ -422,7 +449,10 @@ public class Mission : IComparable<Mission> {
|
|||||||
x => (x.Faction ?? string.Empty),
|
x => (x.Faction ?? string.Empty),
|
||||||
x => x.Influences
|
x => x.Influences
|
||||||
.Where(x => x.SystemAddress != null)
|
.Where(x => x.SystemAddress != null)
|
||||||
.ToDictionary(x => (x.SystemAddress ?? 0), x => x.Influence)
|
.ToDictionary(
|
||||||
|
x => (x.SystemAddress ?? 0),
|
||||||
|
x => x
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ public class PlayerJournal {
|
|||||||
ScanFiles();
|
ScanFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Exception> AllErrors {
|
||||||
|
get {
|
||||||
|
return Files.SelectMany(x => x.Errors).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<JournalFile> Files {
|
public List<JournalFile> Files {
|
||||||
get { return journalfiles; }
|
get { return journalfiles; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,16 @@ public enum ThargoidVessel {
|
|||||||
Basilisk = 4,
|
Basilisk = 4,
|
||||||
Medusa = 5,
|
Medusa = 5,
|
||||||
Hydra = 6,
|
Hydra = 6,
|
||||||
Glaive = 7,
|
// Includes Glaive and Scythe
|
||||||
|
Hunter = 7,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thargoid drone
|
/// Thargoid drone
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Revenant = 8,
|
Revenant = 8,
|
||||||
|
/// <summary>
|
||||||
|
/// New thargoid drone in U17
|
||||||
|
/// </summary>
|
||||||
|
Banshee = 9,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Thargoid {
|
public class Thargoid {
|
||||||
@@ -23,8 +28,10 @@ public class Thargoid {
|
|||||||
{ 25000, ThargoidVessel.Revenant },
|
{ 25000, ThargoidVessel.Revenant },
|
||||||
{ 65000, ThargoidVessel.Scout },
|
{ 65000, ThargoidVessel.Scout },
|
||||||
{ 75000, ThargoidVessel.Scout },
|
{ 75000, ThargoidVessel.Scout },
|
||||||
|
// New in Update 17
|
||||||
|
{ 100000, ThargoidVessel.Banshee },
|
||||||
// New in Update 15
|
// New in Update 15
|
||||||
{ 4500000, ThargoidVessel.Glaive },
|
{ 4500000, ThargoidVessel.Hunter },
|
||||||
{ 6500000, ThargoidVessel.Cyclops },
|
{ 6500000, ThargoidVessel.Cyclops },
|
||||||
{ 20000000, ThargoidVessel.Basilisk },
|
{ 20000000, ThargoidVessel.Basilisk },
|
||||||
//{ 25000000, ThargoidVessel.Orthrus },
|
//{ 25000000, ThargoidVessel.Orthrus },
|
||||||
@@ -46,7 +53,7 @@ public class Thargoid {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public static Dictionary<ThargoidVessel, string?> VesselNames { get; } = new() {
|
public static Dictionary<ThargoidVessel, string?> VesselNames { get; } = new() {
|
||||||
{ ThargoidVessel.Unknown, null },
|
{ ThargoidVessel.Unknown, "(Unknown)" },
|
||||||
{ ThargoidVessel.Revenant, "Revenant" },
|
{ ThargoidVessel.Revenant, "Revenant" },
|
||||||
{ ThargoidVessel.Scout, "Scout" },
|
{ ThargoidVessel.Scout, "Scout" },
|
||||||
{ ThargoidVessel.Orthrus, "Orthrus" },
|
{ ThargoidVessel.Orthrus, "Orthrus" },
|
||||||
@@ -54,7 +61,8 @@ public class Thargoid {
|
|||||||
{ ThargoidVessel.Basilisk, "Basilisk" },
|
{ ThargoidVessel.Basilisk, "Basilisk" },
|
||||||
{ ThargoidVessel.Medusa, "Medusa" },
|
{ ThargoidVessel.Medusa, "Medusa" },
|
||||||
{ ThargoidVessel.Hydra, "Hydra" },
|
{ ThargoidVessel.Hydra, "Hydra" },
|
||||||
{ ThargoidVessel.Glaive, "Glaive" },
|
{ ThargoidVessel.Hunter, "Hunter" },
|
||||||
|
{ ThargoidVessel.Banshee, "Banshee" },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static ThargoidVessel GetVesselByPayout(ulong payout) {
|
public static ThargoidVessel GetVesselByPayout(ulong payout) {
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ public class MissionTest {
|
|||||||
Assert.IsTrue(e.IsEmptyFaction);
|
Assert.IsTrue(e.IsEmptyFaction);
|
||||||
Assert.AreEqual(e.Faction, string.Empty);
|
Assert.AreEqual(e.Faction, string.Empty);
|
||||||
|
|
||||||
string? influence = m.GetInfluenceForFaction("", 251012319587UL);
|
var influence = m.GetInfluenceForFaction("", 251012319587UL);
|
||||||
Assert.IsNotNull(influence);
|
Assert.IsNotNull(influence);
|
||||||
Assert.AreEqual(influence, "+");
|
Assert.AreEqual(influence[0].Influence, "+");
|
||||||
|
|
||||||
e = m.FactionEffects[1];
|
e = m.FactionEffects[1];
|
||||||
Assert.AreEqual(e.Faction, "Social LHS 6103 Confederation");
|
Assert.AreEqual(e.Faction, "Social LHS 6103 Confederation");
|
||||||
@@ -101,22 +101,25 @@ public class MissionTest {
|
|||||||
|
|
||||||
Assert.AreEqual(effect.Reputation, "++");
|
Assert.AreEqual(effect.Reputation, "++");
|
||||||
|
|
||||||
string? influence;
|
var influence = m.GetInfluenceForFaction("Salus Imperial Society", 1865919973739UL);
|
||||||
|
Assert.IsNotNull(influence);
|
||||||
influence = m.GetInfluenceForFaction("Salus Imperial Society", 1865919973739UL);
|
Assert.IsTrue(influence.Length > 0);
|
||||||
Assert.AreEqual(influence, "++");
|
Assert.AreEqual(influence[0].Influence, "++");
|
||||||
|
|
||||||
influence = m.GetInfluenceForFaction("Salus Imperial Society", 1733186884306UL);
|
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);
|
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
|
// Only one entry are we only have Salus
|
||||||
Assert.AreEqual(m.Influences.Count, 1);
|
Assert.AreEqual(m.Influences.Count, 1);
|
||||||
Assert.AreEqual(m.Influences["Salus Imperial Society"].Count, 2);
|
Assert.AreEqual(m.Influences["Salus Imperial Society"].Count, 2);
|
||||||
Assert.AreEqual(m.Influences["Salus Imperial Society"][1865919973739UL], "++");
|
Assert.AreEqual(m.Influences["Salus Imperial Society"][1865919973739UL].Influence, "++");
|
||||||
Assert.AreEqual(m.Influences["Salus Imperial Society"][1733186884306UL], "++");
|
Assert.AreEqual(m.Influences["Salus Imperial Society"][1733186884306UL].Influence, "++");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|||||||
@@ -19,7 +19,13 @@ public class TestTransactionParser {
|
|||||||
return;
|
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.IsNotNull(transactions, "could not parse entries");
|
||||||
Assert.AreEqual(transactions.Count, 3);
|
Assert.AreEqual(transactions.Count, 3);
|
||||||
|
|
||||||
@@ -144,7 +150,14 @@ public class TestTransactionParser {
|
|||||||
return;
|
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.IsNotNull(transactions, "could not parse entries");
|
||||||
Assert.AreEqual(transactions.Count, 1);
|
Assert.AreEqual(transactions.Count, 1);
|
||||||
Assert.IsInstanceOfType(transactions[0], typeof(OrganicData), "result is not of type Organic Data");
|
Assert.IsInstanceOfType(transactions[0], typeof(OrganicData), "result is not of type Organic Data");
|
||||||
|
|||||||
@@ -22,14 +22,17 @@ public class ThargoidKills {
|
|||||||
Assert.IsNotNull(transactions, "could not parse entries");
|
Assert.IsNotNull(transactions, "could not parse entries");
|
||||||
Assert.AreEqual(transactions.Count, 3);
|
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.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.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.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]
|
[TestMethod]
|
||||||
|
|||||||
@@ -1,5 +1,38 @@
|
|||||||
# EliteBGS changelog
|
# EliteBGS changelog
|
||||||
|
|
||||||
|
## 0.4.0 on 13.04.2024
|
||||||
|
|
||||||
|
* Change layout of the results into System -> Faction -> Transaction.
|
||||||
|
Many people who contribute *a lot* of things to the BGS have preferred such
|
||||||
|
a layout to find the right things to post to various discord guilds/threads.
|
||||||
|
* Sort all systems in the new overview by name. It just makes them easier to
|
||||||
|
find when there are a lot of entries.
|
||||||
|
* Add a button to deselect/select all buttons.
|
||||||
|
|
||||||
|
## 0.3.7 on 29.01.2024
|
||||||
|
|
||||||
|
* Fix wrong locations of BGS action if you remain on your carrier while its
|
||||||
|
jumping to a new system.
|
||||||
|
* Identify a capital ship in a high CZ by its music.
|
||||||
|
|
||||||
|
## 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
|
## 0.3.4 on 18.06.2023
|
||||||
|
|
||||||
* Added possibility to specify allied, as well as enemy captain and correspondent.
|
* Added possibility to specify allied, as well as enemy captain and correspondent.
|
||||||
@@ -4,14 +4,12 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using EliteBGS.LogGenerator;
|
using EliteBGS.LogGenerator;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace EliteBGS;
|
namespace EliteBGS;
|
||||||
|
|
||||||
public class DiscordLogGenerator {
|
public class DiscordLogGenerator {
|
||||||
protected List<LogFormatter> formatters = new List<LogFormatter>() {
|
protected List<LogFormatter> formatters = new List<LogFormatter>() {
|
||||||
new MissionFormat(),
|
new MissionFormat(),
|
||||||
new FailedMissionFormat(),
|
|
||||||
new MurderFormat(),
|
new MurderFormat(),
|
||||||
new VoucherFormat(),
|
new VoucherFormat(),
|
||||||
new ThargoidFormatter(),
|
new ThargoidFormatter(),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0-windows</TargetFramework>
|
<TargetFramework>net7.0-windows</TargetFramework>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<Version>0.3.4</Version>
|
<Version>0.4.0</Version>
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
@@ -18,12 +18,15 @@
|
|||||||
<Copyright>Copyright 2019 by Florian Stinglmayr</Copyright>
|
<Copyright>Copyright 2019 by Florian Stinglmayr</Copyright>
|
||||||
<RepositoryUrl>https://codeberg.org/nola/EDBGS</RepositoryUrl>
|
<RepositoryUrl>https://codeberg.org/nola/EDBGS</RepositoryUrl>
|
||||||
<PackageTags>ED;Elite Dangerous;BGS</PackageTags>
|
<PackageTags>ED;Elite Dangerous;BGS</PackageTags>
|
||||||
<PackageProjectUrl>https://bgs.n0la.org</PackageProjectUrl>
|
<PackageProjectUrl>https://salusinvicta.org/bgstool/</PackageProjectUrl>
|
||||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
<Description>Elite: Dangerous BGS logging and reporting tool
|
<Description>Elite: Dangerous BGS logging and reporting tool
|
||||||
</Description>
|
</Description>
|
||||||
<PackageIcon>logo_v5.png</PackageIcon>
|
<PackageIcon>logo_v5.png</PackageIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="main-page.png" />
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Resource Include="main-page.png">
|
<Resource Include="main-page.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
@@ -37,15 +40,10 @@
|
|||||||
<Pack>True</Pack>
|
<Pack>True</Pack>
|
||||||
<PackagePath>\</PackagePath>
|
<PackagePath>\</PackagePath>
|
||||||
</None>
|
</None>
|
||||||
<None Update="docs\CHANGELOG.md">
|
<None Update="CHANGELOG.md">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Resource Include="docs\main-page.png">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Resource>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="LICENCE.txt">
|
<Content Include="LICENCE.txt">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
@@ -55,12 +53,12 @@
|
|||||||
<Resource Include="Salus.ico" />
|
<Resource Include="Salus.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MahApps.Metro" Version="2.4.9" />
|
<PackageReference Include="MahApps.Metro" Version="2.4.10" />
|
||||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||||
<PackageReference Include="Microsoft.Windows.Compatibility" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Windows.Compatibility" Version="8.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
|
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class CombatZoneFormat : LogFormatter {
|
|||||||
var logs = objective
|
var logs = objective
|
||||||
.EnabledOfType<CombatZone>()
|
.EnabledOfType<CombatZone>()
|
||||||
.OrderBy(x => (CombatZones.DifficultyRank(x.Grade) ?? 0))
|
.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())
|
.ToDictionary(x => x.Key, x => x.ToList())
|
||||||
;
|
;
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
@@ -23,6 +23,11 @@ class CombatZoneFormat : LogFormatter {
|
|||||||
int optionals = log.Value
|
int optionals = log.Value
|
||||||
.Sum(x => x.OptionalObjectivesCompleted)
|
.Sum(x => x.OptionalObjectivesCompleted)
|
||||||
;
|
;
|
||||||
|
var settlements = log.Value
|
||||||
|
.Select(x => x.Settlement)
|
||||||
|
.Distinct()
|
||||||
|
;
|
||||||
|
string settl = string.Join(", ", settlements);
|
||||||
if (!string.IsNullOrEmpty(log.Key.Grade)) {
|
if (!string.IsNullOrEmpty(log.Key.Grade)) {
|
||||||
builder.AppendFormat("Won {0}x {1} {2} Combat Zone(s)",
|
builder.AppendFormat("Won {0}x {1} {2} Combat Zone(s)",
|
||||||
log.Value.Count,
|
log.Value.Count,
|
||||||
@@ -39,6 +44,9 @@ class CombatZoneFormat : LogFormatter {
|
|||||||
if (optionals > 0) {
|
if (optionals > 0) {
|
||||||
builder.AppendFormat(" (with {0} optional objectives)", optionals);
|
builder.AppendFormat(" (with {0} optional objectives)", optionals);
|
||||||
}
|
}
|
||||||
|
if (!string.IsNullOrEmpty(settl)) {
|
||||||
|
builder.AppendFormat(" (at {0})", settl);
|
||||||
|
}
|
||||||
builder.Append("\n");
|
builder.Append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,17 +6,72 @@ using EDPlayerJournal.BGS;
|
|||||||
namespace EliteBGS.LogGenerator;
|
namespace EliteBGS.LogGenerator;
|
||||||
|
|
||||||
public class MissionFormat : LogFormatter {
|
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) {
|
public string GenerateLog(Objective objective) {
|
||||||
Dictionary<string, Dictionary<string, int>> collated = new();
|
Dictionary<string, Dictionary<string, int>> collated = new();
|
||||||
Dictionary<string, ulong> passengers = new();
|
Dictionary<string, ulong> passengers = new();
|
||||||
StringBuilder output = new StringBuilder();
|
StringBuilder output = new StringBuilder();
|
||||||
int total_influence = 0;
|
long total_influence = 0;
|
||||||
|
|
||||||
var missions = objective.EnabledOfType<MissionCompleted>();
|
var missions = objective.EnabledOfType<MissionCompleted>();
|
||||||
var support = objective.EnabledOfType<InfluenceSupport>();
|
var support = objective.EnabledOfType<InfluenceSupport>();
|
||||||
|
var failed = objective.EnabledOfType<MissionFailed>();
|
||||||
|
|
||||||
if ((missions == null || missions.Count == 0) &&
|
if ((missions == null || missions.Count == 0) &&
|
||||||
(support == null || support.Count == 0)) {
|
(support == null || support.Count == 0) &&
|
||||||
|
(failed == null || failed.Count == 0)) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,17 +115,25 @@ public class MissionFormat : LogFormatter {
|
|||||||
|
|
||||||
output.Append("\n");
|
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) {
|
foreach (InfluenceSupport inf in support) {
|
||||||
output.Append(inf.ToString());
|
output.Append(inf.ToString());
|
||||||
output.Append("\n");
|
output.Append("\n");
|
||||||
total_influence += inf.Influence.Length;
|
total_influence += inf.Influence.InfluenceAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (support.Count() > 0) {
|
if (support.Count() > 0) {
|
||||||
output.Append("\n");
|
output.Append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (total_influence > 0) {
|
if (total_influence != 0) {
|
||||||
output.AppendFormat("Total Influence: {0}", total_influence);
|
output.AppendFormat("Total Influence: {0}", total_influence);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,13 +147,24 @@ public class MissionFormat : LogFormatter {
|
|||||||
;
|
;
|
||||||
long support = objective
|
long support = objective
|
||||||
.EnabledOfType<InfluenceSupport>()
|
.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 "";
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,71 +9,32 @@
|
|||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Elite: Dangerous BGS Helper" Height="520" Width="950" Icon="Salus.ico" Closing="window_Closing">
|
Title="Elite: Dangerous BGS Helper" Height="520" Width="950" Icon="Salus.ico" Closing="window_Closing">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
|
<local:MinusFortyFiveConverter x:Key="MinusFortyFiveConverter" />
|
||||||
<Style x:Key="StretchingTreeViewStyle" TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
|
<Style x:Key="StretchingTreeViewStyle" TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||||
</Style>
|
</Style>
|
||||||
<local:MinusFortyFiveConverter x:Key="MinusFortyFiveConverter" />
|
|
||||||
</Window.Resources>
|
<local:Report x:Key="ObjectivesBasedOnSystem" />
|
||||||
<mah:MetroWindow.RightWindowCommands>
|
|
||||||
<mah:WindowCommands ShowSeparators="False">
|
<HierarchicalDataTemplate DataType="{x:Type local:SystemObjectives}" ItemsSource="{Binding Path=Objectives}">
|
||||||
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,5,0">
|
<Grid
|
||||||
<Hyperlink x:Name="URL" NavigateUri="https://bgs.n0la.org/" RequestNavigate="URL_RequestNavigate">Homepage</Hyperlink>
|
|
||||||
</TextBlock>
|
|
||||||
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,15,0">
|
|
||||||
<Hyperlink x:Name="SRC" NavigateUri="https://codeberg.org/nola/EDBGS" RequestNavigate="URL_RequestNavigate">Source</Hyperlink>
|
|
||||||
</TextBlock>
|
|
||||||
<mah:ToggleSwitch Content="Dark Theme" x:Name="SwitchTheme" IsOn="True" Toggled="SwitchTheme_Toggled"/>
|
|
||||||
</mah:WindowCommands>
|
|
||||||
</mah:MetroWindow.RightWindowCommands>
|
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="*"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<TabControl Style="{DynamicResource MahApps.Styles.TabControl.Animated}">
|
|
||||||
<TabItem Header="Current Objectives">
|
|
||||||
<Grid>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="*"/>
|
|
||||||
<ColumnDefinition Width="*"/>
|
|
||||||
<ColumnDefinition Width="*"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<ToolBar VerticalAlignment="Top" Grid.Row="0" 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"/>
|
|
||||||
<Separator Margin="1" VerticalAlignment="Center" MinWidth="1" HorizontalAlignment="Center" MinHeight="22"/>
|
|
||||||
<Label Content="From (UTC):" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center"/>
|
|
||||||
<mah:DateTimePicker x:Name="startdate" Height="26.2857142857143" VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
|
||||||
<Label Content="To (UTC):" Height="26.2857142857143" VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
|
||||||
<mah:DateTimePicker x:Name="enddate" Height="26.2857142857143" VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
|
||||||
<Separator Margin="1" VerticalAlignment="Center" MinWidth="1" HorizontalAlignment="Center" MinHeight="22"/>
|
|
||||||
<Button x:Name="ResetTime" Content="Reset Time" Click="ResetTime_Click" />
|
|
||||||
<Separator Margin="1" VerticalAlignment="Center" MinWidth="1" HorizontalAlignment="Center" MinHeight="22"/>
|
|
||||||
<Button x:Name="ManuallyParse" Content="Manually Parse" Click="ManuallyParse_Click" />
|
|
||||||
</ToolBar>
|
|
||||||
<ToolBar Grid.Row="1" HorizontalAlignment="Left" Height="Auto" VerticalAlignment="Top" Width="Auto" Grid.ColumnSpan="3">
|
|
||||||
<Button x:Name="GenerateDiscord" Content="Generate Discord Report" VerticalAlignment="Stretch" Margin="0,0,0,0" VerticalContentAlignment="Center" Click="GenerateDiscord_Click"/>
|
|
||||||
<Separator />
|
|
||||||
<ComboBox x:Name="LogType" VerticalAlignment="Stretch" Margin="0,3,0,3" Width="140" SelectionChanged="LogType_SelectionChanged" />
|
|
||||||
</ToolBar>
|
|
||||||
<TreeView CheckBox.Checked="TreeView_CheckBox_Updated"
|
|
||||||
CheckBox.Unchecked="TreeView_CheckBox_Updated"
|
|
||||||
x:Name="entries" Margin="0,0,0,0"
|
|
||||||
Grid.ColumnSpan="3" Grid.Row="2"
|
|
||||||
KeyUp="entries_KeyUp"
|
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
HorizontalContentAlignment="Stretch"
|
Width="{Binding ActualWidth, ElementName=entries, Converter={StaticResource MinusFortyFiveConverter}}"
|
||||||
>
|
>
|
||||||
<TreeView.ItemTemplate>
|
<Grid.ColumnDefinitions>
|
||||||
<HierarchicalDataTemplate DataType="{x:Type local:Objective}" ItemsSource="{Binding UITransactions}" ItemContainerStyle="{StaticResource StretchingTreeViewStyle}">
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center" Margin="0,2,0,2">
|
||||||
|
<CheckBox Focusable="False" IsChecked="{Binding IsEnabled}" VerticalAlignment="Center"/>
|
||||||
|
<TextBlock Text="System: " Margin="2,0,0,0"/>
|
||||||
|
<TextBlock Text="{Binding SystemName}" FontWeight="DemiBold"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</HierarchicalDataTemplate>
|
||||||
|
|
||||||
|
<HierarchicalDataTemplate DataType="{x:Type local:Objective}"
|
||||||
|
ItemsSource="{Binding Path=UITransactions}"
|
||||||
|
ItemContainerStyle="{StaticResource StretchingTreeViewStyle}">
|
||||||
<Grid
|
<Grid
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Width="{Binding ActualWidth, ElementName=entries, Converter={StaticResource MinusFortyFiveConverter}}"
|
Width="{Binding ActualWidth, ElementName=entries, Converter={StaticResource MinusFortyFiveConverter}}"
|
||||||
@@ -85,10 +46,8 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center" Margin="0,2,0,2">
|
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center" Margin="0,2,0,2">
|
||||||
<CheckBox Focusable="False" IsChecked="{Binding IsEnabled}" VerticalAlignment="Center"/>
|
<CheckBox Focusable="False" IsChecked="{Binding IsEnabled}" VerticalAlignment="Center"/>
|
||||||
<TextBlock Text="System: " Visibility="{Binding HasSystem}" Margin="2,0,0,0"/>
|
<TextBlock Text="Faction: " Margin="2,0,0,0"/>
|
||||||
<TextBlock Text="{Binding System}" FontWeight="DemiBold" Visibility="{Binding HasSystem}"/>
|
<TextBlock Text="{Binding Faction}" FontWeight="DemiBold"/>
|
||||||
<TextBlock Text="Faction: " Visibility="{Binding HasFaction}" Margin="2,0,0,0"/>
|
|
||||||
<TextBlock Text="{Binding Faction}" FontWeight="DemiBold" Visibility="{Binding HasFaction}"/>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<Separator Visibility="Hidden" Grid.Column="1" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" />
|
<Separator Visibility="Hidden" Grid.Column="1" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" />
|
||||||
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Orientation="Horizontal">
|
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Orientation="Horizontal">
|
||||||
@@ -97,8 +56,9 @@
|
|||||||
<Button x:Name="AddCombatZone" Content="Add Combat Zone" Click="AddCombatZone_Click" />
|
<Button x:Name="AddCombatZone" Content="Add Combat Zone" Click="AddCombatZone_Click" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<HierarchicalDataTemplate.ItemTemplate>
|
</HierarchicalDataTemplate>
|
||||||
<HierarchicalDataTemplate>
|
|
||||||
|
<DataTemplate DataType="{x:Type local:UITransaction}">
|
||||||
<!-- This will stretch out the width of the item-->
|
<!-- This will stretch out the width of the item-->
|
||||||
<Grid Initialized="Transaction_Initialized"
|
<Grid Initialized="Transaction_Initialized"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
@@ -148,10 +108,71 @@
|
|||||||
<TextBox x:Name="Profit" MinWidth="80" HorizontalContentAlignment="Right" Text="{Binding Profit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" LostFocus="Profit_LostFocus" KeyUp="Profit_KeyUp"/>
|
<TextBox x:Name="Profit" MinWidth="80" HorizontalContentAlignment="Right" Text="{Binding Profit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" LostFocus="Profit_LostFocus" KeyUp="Profit_KeyUp"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</HierarchicalDataTemplate>
|
</DataTemplate>
|
||||||
</HierarchicalDataTemplate.ItemTemplate>
|
|
||||||
</HierarchicalDataTemplate>
|
</Window.Resources>
|
||||||
</TreeView.ItemTemplate>
|
<mah:MetroWindow.RightWindowCommands>
|
||||||
|
<mah:WindowCommands ShowSeparators="False">
|
||||||
|
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,5,0">
|
||||||
|
<Hyperlink x:Name="URL" NavigateUri="https://salusinvicta.org/bgstool/" RequestNavigate="URL_RequestNavigate">Homepage</Hyperlink>
|
||||||
|
</TextBlock>
|
||||||
|
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,15,0">
|
||||||
|
<Hyperlink x:Name="SRC" NavigateUri="https://codeberg.org/nola/EDBGS" RequestNavigate="URL_RequestNavigate">Source</Hyperlink>
|
||||||
|
</TextBlock>
|
||||||
|
<mah:ToggleSwitch Content="Dark Theme" x:Name="SwitchTheme" IsOn="True" Toggled="SwitchTheme_Toggled"/>
|
||||||
|
</mah:WindowCommands>
|
||||||
|
</mah:MetroWindow.RightWindowCommands>
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TabControl Style="{DynamicResource MahApps.Styles.TabControl.Animated}">
|
||||||
|
<TabItem Header="Current Objectives">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<ToolBar VerticalAlignment="Top" Grid.Row="0" 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"/>
|
||||||
|
<Separator Margin="1" VerticalAlignment="Center" MinWidth="1" HorizontalAlignment="Center" MinHeight="22"/>
|
||||||
|
<Label Content="From (UTC):" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center"/>
|
||||||
|
<mah:DateTimePicker x:Name="startdate" Height="26.2857142857143" VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
||||||
|
<Label Content="To (UTC):" Height="26.2857142857143" VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
||||||
|
<mah:DateTimePicker x:Name="enddate" Height="26.2857142857143" VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
||||||
|
<Separator Margin="1" VerticalAlignment="Center" MinWidth="1" HorizontalAlignment="Center" MinHeight="22"/>
|
||||||
|
<Button x:Name="ResetTime" Content="Reset Time" Click="ResetTime_Click" />
|
||||||
|
<Separator Margin="1" VerticalAlignment="Center" MinWidth="1" HorizontalAlignment="Center" MinHeight="22"/>
|
||||||
|
<Button x:Name="ManuallyParse" Content="Manually Parse" Click="ManuallyParse_Click" />
|
||||||
|
</ToolBar>
|
||||||
|
<ToolBar Grid.Row="1" HorizontalAlignment="Left" Height="Auto" VerticalAlignment="Top" Width="Auto" Grid.ColumnSpan="3">
|
||||||
|
<Button x:Name="GenerateDiscord" Content="Generate Discord Report" VerticalAlignment="Stretch" Margin="0,0,0,0" VerticalContentAlignment="Center" Click="GenerateDiscord_Click"/>
|
||||||
|
<Separator />
|
||||||
|
<ComboBox x:Name="LogType" VerticalAlignment="Stretch" Margin="0,3,0,3" Width="140" SelectionChanged="LogType_SelectionChanged" />
|
||||||
|
<Separator />
|
||||||
|
<CheckBox x:Name="SelectAll" Content="Select All" IsChecked="True" Click="SelectAll_Click"/>
|
||||||
|
</ToolBar>
|
||||||
|
<TreeView CheckBox.Checked="TreeView_CheckBox_Updated"
|
||||||
|
CheckBox.Unchecked="TreeView_CheckBox_Updated"
|
||||||
|
x:Name="entries" Margin="0,0,0,0"
|
||||||
|
Grid.ColumnSpan="3"
|
||||||
|
Grid.Row="2"
|
||||||
|
KeyUp="entries_KeyUp"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
HorizontalContentAlignment="Stretch"
|
||||||
|
ItemsSource="{Binding Source={StaticResource ObjectivesBasedOnSystem}}"
|
||||||
|
>
|
||||||
<TreeView.ItemContainerStyle>
|
<TreeView.ItemContainerStyle>
|
||||||
<Style TargetType="TreeViewItem">
|
<Style TargetType="TreeViewItem">
|
||||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
|
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ public partial class MainWindow : MetroWindow {
|
|||||||
//{ "HouseSalus", Color.FromRgb(0xBC, 0x94, 0x39) },
|
//{ "HouseSalus", Color.FromRgb(0xBC, 0x94, 0x39) },
|
||||||
{ "HouseSalus", Color.FromRgb(0xED, 0xDA, 0x70) },
|
{ "HouseSalus", Color.FromRgb(0xED, 0xDA, 0x70) },
|
||||||
{ "NovaNavy", Color.FromRgb(0xA1, 0xA4, 0xDB) },
|
{ "NovaNavy", Color.FromRgb(0xA1, 0xA4, 0xDB) },
|
||||||
|
// Official Red of the Polish Flag
|
||||||
|
{ "PolskaGurom", Color.FromRgb(0xD4, 0x21, 0x3D) },
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var colourtheme in colorThemes) {
|
foreach (var colourtheme in colorThemes) {
|
||||||
@@ -192,7 +194,7 @@ public partial class MainWindow : MetroWindow {
|
|||||||
transactions.RemoveAll(x => incompletes.Contains(x));
|
transactions.RemoveAll(x => incompletes.Contains(x));
|
||||||
|
|
||||||
report = new Report(transactions);
|
report = new Report(transactions);
|
||||||
this.entries.ItemsSource = report.Objectives;
|
this.entries.ItemsSource = report.SystemObjectives;
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
Log("Something went terribly wrong while parsing the E:D player journal.");
|
Log("Something went terribly wrong while parsing the E:D player journal.");
|
||||||
Log("Please send this to CMDR Hekateh:");
|
Log("Please send this to CMDR Hekateh:");
|
||||||
@@ -233,6 +235,12 @@ public partial class MainWindow : MetroWindow {
|
|||||||
|
|
||||||
HandleEntries(entries, start, end);
|
HandleEntries(entries, start, end);
|
||||||
GenerateLog();
|
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) {
|
} catch (Exception exception) {
|
||||||
Log("Something went terribly wrong while parsing the E:D player journal.");
|
Log("Something went terribly wrong while parsing the E:D player journal.");
|
||||||
Log("Please send this to CMDR Hekateh:");
|
Log("Please send this to CMDR Hekateh:");
|
||||||
@@ -265,15 +273,27 @@ public partial class MainWindow : MetroWindow {
|
|||||||
object obj = entries.SelectedItem;
|
object obj = entries.SelectedItem;
|
||||||
bool removed = false;
|
bool removed = false;
|
||||||
|
|
||||||
if (obj.GetType() == typeof(Objective)) {
|
if (obj.GetType() == typeof(SystemObjectives)) {
|
||||||
removed = report.Objectives.Remove(obj as Objective);
|
removed = report.SystemObjectives.Remove(obj as SystemObjectives);
|
||||||
} else if (obj.GetType() == typeof(UITransaction) ||
|
} else if (obj.GetType() == typeof(Objective)) {
|
||||||
obj.GetType().IsSubclassOf(typeof(UITransaction))) {
|
report
|
||||||
foreach (Objective parent in report.Objectives) {
|
.SystemObjectives
|
||||||
if (parent.UITransactions.Remove(obj as UITransaction)) {
|
.ForEach(x => {
|
||||||
|
if (x.Objectives.Remove(obj as Objective)) {
|
||||||
removed = true;
|
removed = true;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
} else if (obj.GetType() == typeof(UITransaction) ||
|
||||||
|
obj.GetType().IsSubclassOf(typeof(UITransaction))) {
|
||||||
|
report
|
||||||
|
.SystemObjectives
|
||||||
|
.SelectMany(x =>
|
||||||
|
x.Objectives
|
||||||
|
.Where(x => x.UITransactions.Contains(obj as UITransaction))
|
||||||
|
)
|
||||||
|
.ToList()
|
||||||
|
.ForEach(x => removed = x.UITransactions.Remove(obj as UITransaction))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removed) {
|
if (removed) {
|
||||||
@@ -551,4 +571,11 @@ public partial class MainWindow : MetroWindow {
|
|||||||
} catch (Exception) {
|
} catch (Exception) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SelectAll_Click(object sender, RoutedEventArgs e) {
|
||||||
|
if (report == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
report.SystemObjectives.ForEach(t => { t.IsEnabled = (bool)SelectAll.IsChecked; });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public class MinusFortyFiveConverter : IValueConverter {
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public object Convert(
|
public object Convert(
|
||||||
object value, Type targetType, object parameter, CultureInfo culture) {
|
object value, Type targetType, object parameter, CultureInfo culture) {
|
||||||
return (double)value - 80;
|
return (double)value - 110;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ public class UITransaction : INotifyPropertyChanged {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class Objective : IComparable<Objective> {
|
public class Objective : IComparable<Objective> {
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; } = true;
|
||||||
|
|
||||||
public List<UITransaction> UITransactions { get; } = new List<UITransaction>();
|
public List<UITransaction> UITransactions { get; } = new List<UITransaction>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Resources;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows;
|
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
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("0.3.4.0")]
|
[assembly: AssemblyVersion("0.4.0.0")]
|
||||||
[assembly: AssemblyFileVersion("0.3.4.0")]
|
[assembly: AssemblyFileVersion("0.4.0.0")]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ been parsed, you may then generate a BGS report you can copy/paste into Discord.
|
|||||||
|
|
||||||
Source code is available at [https://codeberg.org/nola/edbgs](https://codeberg.org/nola/edbgs).
|
Source code is available at [https://codeberg.org/nola/edbgs](https://codeberg.org/nola/edbgs).
|
||||||
|
|
||||||
Binary downloads can be found here: [https://bgs.n0la.org/](https://bgs.n0la.org/).
|
Binary downloads can be found here: [https://salusinvicta.org/bgstool/](https://salusinvicta.org/bgstool/).
|
||||||
|
|
||||||
## How To
|
## How To
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,38 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
using EDPlayerJournal.BGS;
|
using EDPlayerJournal.BGS;
|
||||||
|
|
||||||
namespace EliteBGS;
|
namespace EliteBGS;
|
||||||
|
|
||||||
|
public class SystemObjectives : INotifyPropertyChanged, IComparable<SystemObjectives> {
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
private bool isenabled = true;
|
||||||
|
|
||||||
|
public bool IsEnabled {
|
||||||
|
get { return isenabled; }
|
||||||
|
set {
|
||||||
|
isenabled = value;
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsEnabled"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsExpanded { get; set; } = false;
|
||||||
|
|
||||||
|
public string SystemName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public List<Objective> Objectives { get; set; } = new();
|
||||||
|
|
||||||
|
public int CompareTo(SystemObjectives other) {
|
||||||
|
if (other == null) return 1;
|
||||||
|
return string.Compare(SystemName, other.SystemName, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class Report {
|
public class Report {
|
||||||
public List<Objective> Objectives { get; set; } = new List<Objective>();
|
public List<SystemObjectives> SystemObjectives { get; set; } = new();
|
||||||
|
|
||||||
public Report() { }
|
public Report() { }
|
||||||
|
|
||||||
@@ -12,29 +40,35 @@ public class Report {
|
|||||||
Populate(transactions);
|
Populate(transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Objective> Objectives {
|
||||||
|
get {
|
||||||
|
return SystemObjectives
|
||||||
|
.Where(t => t.IsEnabled)
|
||||||
|
.SelectMany(x => x.Objectives)
|
||||||
|
.ToList()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Populate(List<Transaction> transactions) {
|
private void Populate(List<Transaction> transactions) {
|
||||||
if (transactions == null || transactions.Count == 0) {
|
if (transactions == null || transactions.Count == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Transaction t in transactions) {
|
foreach (Transaction t in transactions) {
|
||||||
Objective o;
|
var o = SystemObjectives.Find(x => string.Compare(x.SystemName, t.System) == 0);
|
||||||
if (t.SystemContribution) {
|
|
||||||
o = Objectives.Find(x => x.Matches(t.System));
|
|
||||||
} else {
|
|
||||||
o = Objectives.Find(x => x.Matches(t.System, t.Faction));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
if (t.SystemContribution) {
|
o = new SystemObjectives() { SystemName = t.System };
|
||||||
o = new Objective() { System = t.System };
|
SystemObjectives.Add(o);
|
||||||
} else {
|
|
||||||
o = new Objective() { Faction = t.Faction, System = t.System };
|
|
||||||
}
|
}
|
||||||
Objectives.Add(o);
|
var objective = o.Objectives.Find(x => x.Matches(t.System, t.Faction));
|
||||||
|
if (objective == null) {
|
||||||
|
objective = new Objective() { Faction = t.Faction, System = t.System };
|
||||||
|
o.Objectives.Add(objective);
|
||||||
|
}
|
||||||
|
objective.UITransactions.Add(new UITransaction(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
o.UITransactions.Add(new UITransaction(t));
|
SystemObjectives.Sort();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
EliteBGS/combatzone.png
Normal file
BIN
EliteBGS/combatzone.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 68 KiB |
@@ -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
|
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
|
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.
|
the faction of the NPC.
|
||||||
|
|
||||||
### Why does cartography data, and sold cargo show up for the wrong faction, but for the right station/system?
|
### Why does cartography data, and sold cargo show up for the wrong faction, but for the right station/system?
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ command line:
|
|||||||
winget install Microsoft.DotNet.DesktopRuntime.7
|
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.7** at CodeBerg:
|
||||||
|
|
||||||
* [https://codeberg.org/nola/EDBGS/releases](https://codeberg.org/nola/EDBGS/releases)
|
* [https://codeberg.org/nola/EDBGS/releases](https://codeberg.org/nola/EDBGS/releases)
|
||||||
|
|
||||||
Or alternatively from my server:
|
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.7.zip](https://bgs.n0la.org/elitebgs-0.3.7.zip)
|
||||||
|
|
||||||
## Old Versions
|
## Old Versions
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 67 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 74 KiB |
@@ -1,15 +0,0 @@
|
|||||||
site_name: EliteBGS
|
|
||||||
|
|
||||||
markdown_extensions:
|
|
||||||
- pymdownx.snippets:
|
|
||||||
check_paths: true
|
|
||||||
|
|
||||||
theme:
|
|
||||||
name: lumen
|
|
||||||
|
|
||||||
nav:
|
|
||||||
- Overview: 'index.md'
|
|
||||||
- "Detailed Description": 'description.md'
|
|
||||||
- "Combat Zones": 'combatzones.md'
|
|
||||||
- FAQ: 'faq.md'
|
|
||||||
- Changelog: 'CHANGELOG.md'
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
EDBGS is a project containing the EliteBGS BGS application. It also contains the dotnet
|
EDBGS is a project containing the EliteBGS BGS application. It also contains the dotnet
|
||||||
class library EDPlayerJournal, which reads and parses Elite Dangerous player journals.
|
class library EDPlayerJournal, which reads and parses Elite Dangerous player journals.
|
||||||
|
|
||||||
See [https://bgs.n0la.org/](https://bgs.n0la.org) for further details.
|
See [https://salusinvicta.org/bgstool/](https://salusinvicta.org/bgstool/) for further details.
|
||||||
|
|
||||||
The tool helps with creating BGS reports for squadrons that support factions in
|
The tool helps with creating BGS reports for squadrons that support factions in
|
||||||
Elite: Dangerous that can be copy and pasted into a Discord server. It finds all BGS
|
Elite: Dangerous that can be copy and pasted into a Discord server. It finds all BGS
|
||||||
|
|||||||
Reference in New Issue
Block a user