Compare commits

...

6 Commits

14 changed files with 225 additions and 40 deletions

View File

@ -28,7 +28,7 @@ public class ThargoidKill : Transaction {
public ThargoidKill() { }
public ThargoidKill(FactionKillBondEntry entry) {
if (string.Compare(entry.VictimFaction, Thargoid.ThargoidFaction) != 0) {
if (!Factions.IsThargoid(entry.VictimFaction)) {
throw new Exception("Not a valid thargoid kill");
}

View File

@ -484,26 +484,42 @@ internal class RedeemVoucherParser : TransactionParserPart {
if (current_factions == null) {
transactions.AddIncomplete(new Vouchers(),
"Current system factions are unknown, so vouchers were ineffective");
return;
}
foreach (string faction in entry.Factions) {
if (current_factions.Find(x => string.Compare(x.Name, faction, true) == 0) == null) {
transactions.AddIncomplete(new Vouchers(),
string.Format("Vouchers for {0} were ignored in {1} since said " +
"faction is not present here", faction, context.CurrentSystem)
);
continue;
bool relevantBond = false;
string relevantFaction = faction;
if (string.Compare(faction, Factions.PilotsFederationVouchers) == 0) {
// Target faction is pilots' federation, so we assume thargoid bonks
// Also assign this combat bond to the Pilots Federation
relevantFaction = Factions.PilotsFederation;
relevantBond = true;
}
if (current_factions != null && !relevantBond) {
// If we have local factions, and it ain't thargoid bonds see if the bonds were
// useful in the current system
if (current_factions.Find(x => string.Compare(x.Name, faction, true) == 0) != null) {
relevantBond = true;
} else {
transactions.AddIncomplete(new Vouchers(),
string.Format("Vouchers for {0} had no effect in {1} since said " +
"faction is not present here", faction, context.CurrentSystem)
);
}
}
if (relevantBond) {
transactions.Add(new Vouchers(entry) {
System = context.CurrentSystem,
Station = context.CurrentStation,
Faction = faction,
Faction = relevantFaction,
ControllingFaction = context.ControllingFaction,
});
}
}
}
}
internal class SellMicroResourcesParser : TransactionParserPart {
@ -587,9 +603,13 @@ internal class FactionKillBondParser : TransactionParserPart {
throw new NotImplementedException();
}
if (string.Compare(entry.VictimFaction, Thargoid.ThargoidFaction) == 0) {
if (Factions.IsThargoid(entry.VictimFaction)) {
// Thargoid bonk
transactions.Add(new ThargoidKill(entry));
transactions.Add(new ThargoidKill(entry) {
System = context.CurrentSystem,
Faction = Factions.PilotsFederation,
Station = context.CurrentStation,
});
}
}
}

View File

@ -20,8 +20,8 @@ public class Vouchers : Transaction {
}
return Entries
.OfType<RedeemVoucherEntry>()
.Where(x => x.FactionBounties.ContainsKey(Faction))
.Sum(x => x.FactionBounties[Faction])
.ToList()
.Sum(x => (long)x.GetBountyForFaction(Faction))
;
}
}

View File

@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace EDPlayerJournal.Entries;
public class RedeemVoucherEntry : Entry {
protected override void Initialise() {
Amount = (JSON.Value<int?>("Amount") ?? 0);
Amount = (JSON.Value<ulong?>("Amount") ?? 0);
Type = JSON.Value<string>("Type");
/* according to API, there should be a Factions structure */
@ -12,7 +12,7 @@ public class RedeemVoucherEntry : Entry {
if (factions != null) {
foreach (JObject faction in factions.Children<JObject>()) {
string? faction_name = faction.Value<string>("Faction");
long? faction_bounty = faction.Value<long?>("Amount");
ulong? faction_bounty = faction.Value<ulong?>("Amount");
if (faction_name == null || faction_name.Length <= 0 || faction_bounty == null) {
continue;
}
@ -35,8 +35,29 @@ public class RedeemVoucherEntry : Entry {
}
}
public int Amount { get; set; } = 0;
public ulong GetBountyForFaction(string? a) {
if (a == null) {
return 0;
}
var relevant = FactionBounties.Where(x => EDPlayerJournal.Factions.CompareFactions(x.Key, a) == 0).ToList();
if (relevant == null || relevant.Count() == 0) {
return 0;
}
return (ulong)relevant.Sum(x => (decimal)x.Value);
}
public ulong Amount { get; set; } = 0;
public string? Type { get; set; } = "Bounty";
public List<string> Factions { get; set; } = new List<string>();
public Dictionary<string, long> FactionBounties { get; set; } = new Dictionary<string, long>();
/// <summary>
/// List of factions
/// </summary>
public List<string> Factions { get; set; } = new();
/// <summary>
/// Bounties awarded by faction
/// </summary>
public Dictionary<string, ulong> FactionBounties { get; set; } = new();
}

View File

@ -33,12 +33,78 @@ public class Factions {
/// <summary>
/// Internal name for the Pilots Federation faction
/// </summary>
public static string PilotsFederation = "$faction_PilotsFederation;";
public static string PilotsFederationInternal = "$faction_PilotsFederation;";
/// <summary>
/// Name used for Pilots Federation in vouchers
/// </summary>
public static string PilotsFederationVouchers = "PilotsFederation";
/// <summary>
/// Friendly name of the Pilots Federation
/// </summary>
public static string PilotsFederation = "Pilots' Federation";
/// <summary>
/// Internal name for the Thargoid faction
/// </summary>
public static string Thargoid = "$faction_Thargoid;";
public static string ThargoidInternal = "$faction_Thargoid;";
/// <summary>
/// Localised name of the Thargoids
/// </summary>
public static string Thargoid = "Thargoids";
public static bool IsPilotsFederation(string? name) {
if (name == null) {
return false;
}
if (string.Compare(name, PilotsFederationInternal) == 0 ||
string.Compare(name, PilotsFederationVouchers) == 0 ||
string.Compare(name, PilotsFederation) == 0) {
return true;
}
return false;
}
public static bool IsThargoid(string? name) {
if (name == null) {
return false;
}
if (string.Compare(name, ThargoidInternal) == 0 ||
string.Compare(name, Thargoid) == 0) {
return true;
}
return false;
}
/// <summary>
/// Compares two factions names and sees if they are the same faction. Since
/// factions can have an internal name, and a public name, this function takes
/// these into account.
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static int CompareFactions(string? a, string? b) {
if (a == null || b == null) {
return -1;
}
if (IsPilotsFederation(a) && IsPilotsFederation(b)) {
return 0;
}
if (IsThargoid(a) && IsThargoid(b)) {
return 0;
}
return string.Compare(a, b);
}
}
public class Faction {

View File

@ -44,6 +44,9 @@
<None Update="SellOrganicData.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ThargoidBonds.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ThargoidKills.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>

View File

@ -0,0 +1,3 @@
{ "timestamp":"2022-11-25T10:10:43Z", "event":"FSDJump", "Taxi":false, "Multicrew":false, "StarSystem":"Nyalayan", "SystemAddress":1458309042898, "StarPos":[29.71875,-172.71875,-6.46875], "SystemAllegiance":"Independent", "SystemEconomy":"$economy_Agri;", "SystemEconomy_Localised":"Agriculture", "SystemSecondEconomy":"$economy_Refinery;", "SystemSecondEconomy_Localised":"Refinery", "SystemGovernment":"$government_Theocracy;", "SystemGovernment_Localised":"Theocracy", "SystemSecurity":"$SYSTEM_SECURITY_medium;", "SystemSecurity_Localised":"Medium Security", "Population":1920608781, "Body":"Nyalayan A", "BodyID":1, "BodyType":"Star", "JumpDist":7.769, "FuelUsed":0.142448, "FuelLevel":15.857553, "Factions":[ { "Name":"Nyalayan Imperial Society", "FactionState":"Election", "Government":"Patronage", "Influence":0.165138, "Allegiance":"Empire", "Happiness":"$Faction_HappinessBand2;", "Happiness_Localised":"Happy", "MyReputation":17.496799, "ActiveStates":[ { "State":"Election" } ] }, { "Name":"Reret Emperor's Grace", "FactionState":"War", "Government":"Patronage", "Influence":0.257900, "Allegiance":"Empire", "Happiness":"$Faction_HappinessBand2;", "Happiness_Localised":"Happy", "MyReputation":100.000000, "ActiveStates":[ { "State":"Expansion" }, { "State":"War" } ] }, { "Name":"Nyalayan Silver Transport Org", "FactionState":"None", "Government":"Corporate", "Influence":0.076453, "Allegiance":"Empire", "Happiness":"$Faction_HappinessBand2;", "Happiness_Localised":"Happy", "MyReputation":81.875000 }, { "Name":"Nyalayan Power & Co", "FactionState":"None", "Government":"Corporate", "Influence":0.060143, "Allegiance":"Independent", "Happiness":"$Faction_HappinessBand2;", "Happiness_Localised":"Happy", "MyReputation":23.173201 }, { "Name":"Amanogawa Enlight", "FactionState":"War", "Government":"Theocracy", "Influence":0.257900, "Allegiance":"Independent", "Happiness":"$Faction_HappinessBand2;", "Happiness_Localised":"Happy", "MyReputation":-1.210600, "ActiveStates":[ { "State":"Expansion" }, { "State":"War" } ] }, { "Name":"Nyalayan Crimson Dragons", "FactionState":"None", "Government":"Anarchy", "Influence":0.017329, "Allegiance":"Independent", "Happiness":"$Faction_HappinessBand2;", "Happiness_Localised":"Happy", "MyReputation":-13.530000 }, { "Name":"Traditional Nyalayan Front", "FactionState":"Election", "Government":"Dictatorship", "Influence":0.165138, "Allegiance":"Independent", "Happiness":"$Faction_HappinessBand2;", "Happiness_Localised":"Happy", "MyReputation":64.699997, "ActiveStates":[ { "State":"Election" } ] } ], "SystemFaction":{ "Name":"Amanogawa Enlight", "FactionState":"War" }, "Conflicts":[ { "WarType":"election", "Status":"active", "Faction1":{ "Name":"Nyalayan Imperial Society", "Stake":"Pilcher Port", "WonDays":2 }, "Faction2":{ "Name":"Traditional Nyalayan Front", "Stake":"Lamar Falls", "WonDays":0 } }, { "WarType":"war", "Status":"active", "Faction1":{ "Name":"Reret Emperor's Grace", "Stake":"", "WonDays":1 }, "Faction2":{ "Name":"Amanogawa Enlight", "Stake":"Sutter Ring", "WonDays":2 } } ] }
{ "timestamp":"2022-11-25T10:13:32Z", "event":"Docked", "StationName":"Pilcher Port", "StationType":"Orbis", "Taxi":false, "Multicrew":false, "StarSystem":"Nyalayan", "SystemAddress":1458309042898, "MarketID":3222853120, "StationFaction":{ "Name":"Nyalayan Imperial Society", "FactionState":"Election" }, "StationGovernment":"$government_Patronage;", "StationGovernment_Localised":"Patronage", "StationAllegiance":"Empire", "StationServices":[ "dock", "autodock", "commodities", "contacts", "exploration", "missions", "outfitting", "crewlounge", "rearm", "refuel", "repair", "shipyard", "tuning", "engineer", "missionsgenerated", "flightcontroller", "stationoperations", "powerplay", "searchrescue", "stationMenu", "shop", "livery", "socialspace", "bartender", "vistagenomics", "pioneersupplies", "apexinterstellar", "frontlinesolutions" ], "StationEconomy":"$economy_Refinery;", "StationEconomy_Localised":"Refinery", "StationEconomies":[ { "Name":"$economy_Refinery;", "Name_Localised":"Refinery", "Proportion":1.000000 } ], "DistFromStarLS":76.465557, "LandingPads":{ "Small":8, "Medium":11, "Large":6 } }
{ "timestamp":"2022-11-25T10:13:53Z", "event":"RedeemVoucher", "Type":"CombatBond", "Amount":24240000, "Faction":"PilotsFederation" }

View File

@ -1,10 +1,6 @@
using EDPlayerJournal.BGS;
using EDPlayerJournal;
using EDPlayerJournal.BGS;
using EDPlayerJournal.Entries;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EDPlayerJournalTests;
@ -21,13 +17,38 @@ public class ThargoidKills {
return;
}
List<Transaction>? transactions = parser.Parse(entries);
List<ThargoidKill>? transactions = parser.Parse(entries)?.OfType<ThargoidKill>().ToList();
Assert.IsNotNull(transactions, "could not parse entries");
Assert.AreEqual(transactions.Count, 4);
Assert.AreEqual(transactions.Count, 3);
Assert.IsInstanceOfType(transactions[0], typeof(ThargoidKill), "result is not of type ThargoidKill");
Assert.AreEqual(transactions[0].ThargoidType, EDPlayerJournal.ThargoidVessel.Scout);
Assert.IsInstanceOfType(transactions[1], typeof(ThargoidKill), "result is not of type ThargoidKill");
Assert.AreEqual(transactions[1].ThargoidType, EDPlayerJournal.ThargoidVessel.Basilisk);
Assert.IsInstanceOfType(transactions[2], typeof(ThargoidKill), "result is not of type ThargoidKill");
Assert.AreEqual(transactions[2].ThargoidType, EDPlayerJournal.ThargoidVessel.Scout);
}
[TestMethod]
public void ThargoidBonds() {
TransactionParser parser = new();
List<Entry>? entries = Helper.LoadTestData("ThargoidBonds.txt");
Assert.IsNotNull(entries, "could not load test data");
if (entries == null) {
return;
}
List<Vouchers>? transactions = parser.Parse(entries)?.OfType<Vouchers>().ToList();
Assert.IsNotNull(transactions, "could not parse entries");
Assert.AreEqual(transactions.Count, 1);
Assert.AreEqual(transactions[0].Faction, Factions.PilotsFederationVouchers);
Assert.AreEqual(transactions[0].TotalSum, 24240000L);
Assert.AreEqual(transactions[0].Type, "Combat Bond");
}
}

View File

@ -1,4 +1,3 @@
{ "timestamp":"2022-11-25T09:50:45Z", "event":"FactionKillBond", "Reward":80000, "AwardingFaction":"$faction_PilotsFederation;", "AwardingFaction_Localised":"Pilots' Federation", "VictimFaction":"$faction_Thargoid;", "VictimFaction_Localised":"Thargoids" }
{ "timestamp":"2022-11-25T09:52:28Z", "event":"FactionKillBond", "Reward":24000000, "AwardingFaction":"$faction_PilotsFederation;", "AwardingFaction_Localised":"Pilots' Federation", "VictimFaction":"$faction_Thargoid;", "VictimFaction_Localised":"Thargoids" }
{ "timestamp":"2022-11-25T09:47:19Z", "event":"FactionKillBond", "Reward":80000, "AwardingFaction":"$faction_PilotsFederation;", "AwardingFaction_Localised":"Pilots' Federation", "VictimFaction":"$faction_Thargoid;", "VictimFaction_Localised":"Thargoids" }
{ "timestamp":"2022-11-25T10:13:53Z", "event":"RedeemVoucher", "Type":"CombatBond", "Amount":24240000, "Faction":"PilotsFederation" }

View File

@ -12,6 +12,7 @@ public class DiscordLogGenerator {
new FailedMissionFormat(),
new MurderFormat(),
new VoucherFormat(),
new ThargoidFormatter(),
new CombatZoneFormat(),
new KillBondsFormat(),
new CartographicsFormat(),
@ -33,9 +34,18 @@ public class DiscordLogGenerator {
protected virtual string GenerateObjectiveHeader(Objective objective) {
StringBuilder log = new StringBuilder();
string location;
if (!string.IsNullOrEmpty(objective.System) && !string.IsNullOrEmpty(objective.Faction)) {
location = string.Format("{0}, {1}", objective.System, objective.Faction);
} else if (!string.IsNullOrEmpty(objective.System)) {
location = objective.System;
} else {
location = "Unknown Location";
}
log.AppendFormat("**Date:** {0}\n", DateTime.Now.ToString("dd/MM/yyyy"));
log.AppendFormat("**Location:** {0}, {1}\n", objective.System, objective.Faction);
log.AppendFormat("**Faction:** {0}\n", objective.Faction);
log.AppendFormat("**Target:** {0}\n", location);
log.AppendLine("");
log.AppendLine("```");

View File

@ -0,0 +1,32 @@
using EDPlayerJournal;
using EDPlayerJournal.BGS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EliteBGS.LogGenerator;
public class ThargoidFormatter : LogFormatter {
public string GenerateLog(Objective objective) {
List<ThargoidKill> kills = objective.EnabledOfType<ThargoidKill>().ToList();
if (kills.Count == 0 ) {
return "";
}
Dictionary<ThargoidVessel, List<ThargoidKill>> sorted = kills
.GroupBy(x => x.ThargoidType)
.ToDictionary(x => x.Key, x => x.ToList())
;
StringBuilder builder = new StringBuilder();
foreach (var k in sorted) {
string name = Thargoid.GetVesselName(k.Key);
builder.AppendFormat("{0}x {1}(s) killed\n", k.Value.Count, name);
}
return builder.ToString();
}
}

View File

@ -19,9 +19,7 @@ public class VoucherFormat : LogFormatter {
}
foreach (var m in missions) {
builder.AppendFormat("Handed in {0} vouchers for {1}\n", m.Type, m.Faction);
builder.AppendFormat("(Total value: {0})\n", Credits.FormatCredits(m.TotalSum));
builder.AppendFormat("\n");
builder.AppendFormat("Handed in {0} vouchers: {1}\n", m.Type, Credits.FormatCredits(m.TotalSum));
}
return builder.ToString().Trim();

View File

@ -34,7 +34,17 @@ public class NonaDiscordLog : DiscordLogGenerator {
protected override string GenerateObjectiveHeader(Objective objective) {
StringBuilder log = new StringBuilder();
log.AppendFormat(":globe_with_meridians: `Location:` {0}, {1}\n", objective.System, objective.Faction);
string location;
if (!string.IsNullOrEmpty(objective.System) && !string.IsNullOrEmpty(objective.Faction)) {
location = string.Format("{0}, {1}", objective.System, objective.Faction);
} else if (!string.IsNullOrEmpty(objective.System)) {
location = objective.System;
} else {
location = "Unknown Location";
}
log.AppendFormat(":globe_with_meridians: `Target:` {0}\n", location);
log.Append(":clipboard: `Conducted:`\n");
log.Append("```");

View File

@ -77,6 +77,8 @@ public class Objective : IComparable<Objective> {
StringBuilder str = new StringBuilder();
if (!string.IsNullOrEmpty(System)) {
str.AppendFormat("System: {0}", System);
} else {
str.AppendFormat("System: Unknown");
}
if (!string.IsNullOrEmpty(Faction)) {
if (str.Length > 0) {