move mission related logic to mission class
This commit is contained in:
		
							parent
							
								
									ce54430137
								
							
						
					
					
						commit
						f4bbdfd1b3
					
				| @ -25,8 +25,8 @@ public class InfluenceSupport : Transaction { | |||||||
|         StringBuilder builder = new StringBuilder(); |         StringBuilder builder = new StringBuilder(); | ||||||
|         string? missionname; |         string? missionname; | ||||||
| 
 | 
 | ||||||
|         if (RelevantMission != null) { |         if (RelevantMission != null && RelevantMission.Mission != null) { | ||||||
|             missionname = RelevantMission.HumanReadableName; |             missionname = RelevantMission.Mission.LocalisedName; | ||||||
|         } else { |         } else { | ||||||
|             missionname = "UNKNOWN MISSION"; |             missionname = "UNKNOWN MISSION"; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -12,14 +12,14 @@ public class MissionCompleted : Transaction { | |||||||
|     public string MissionName { |     public string MissionName { | ||||||
|         get { |         get { | ||||||
|             MissionCompletedEntry? c = Entries[0] as MissionCompletedEntry; |             MissionCompletedEntry? c = Entries[0] as MissionCompletedEntry; | ||||||
|             if (c == null) { |             if (c == null || c.Mission == null) { | ||||||
|                 return ""; |                 return ""; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (string.IsNullOrEmpty(c.HumanReadableName)) { |             if (string.IsNullOrEmpty(c.Mission.LocalisedName)) { | ||||||
|                 return (c.Name ?? ""); |                 return (c.Mission.Name ?? ""); | ||||||
|             } else { |             } else { | ||||||
|                 return c.HumanReadableName; |                 return c.Mission.LocalisedName; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -28,15 +28,11 @@ public class MissionCompleted : Transaction { | |||||||
|         get { |         get { | ||||||
|             MissionCompletedEntry? e = (Entries[0] as MissionCompletedEntry); |             MissionCompletedEntry? e = (Entries[0] as MissionCompletedEntry); | ||||||
| 
 | 
 | ||||||
|             if (e == null || Faction == null) { |             if (e == null || Faction == null || e.Mission == null) { | ||||||
|                 return ""; |                 return ""; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (SystemAddress == 0) { |             return (e.Mission.GetInfluenceForFaction(Faction, SystemAddress) ?? ""); | ||||||
|                 return (e.GetInfluenceForFaction(Faction) ?? ""); |  | ||||||
|             } else { |  | ||||||
|                 return (e.GetInfluenceForFaction(Faction, SystemAddress) ?? ""); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -48,11 +44,11 @@ public class MissionCompleted : Transaction { | |||||||
|         StringBuilder builder = new StringBuilder(); |         StringBuilder builder = new StringBuilder(); | ||||||
|         var entry = Entries[0] as MissionCompletedEntry; |         var entry = Entries[0] as MissionCompletedEntry; | ||||||
| 
 | 
 | ||||||
|         if (entry == null) { |         if (entry == null || entry.Mission == null) { | ||||||
|             return ""; |             return ""; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         var influence = entry.GetInfluenceForFaction(Faction, SystemAddress); |         var influence = entry.Mission.GetInfluenceForFaction(Faction, SystemAddress); | ||||||
| 
 | 
 | ||||||
|         builder.AppendFormat("{0}", MissionName); |         builder.AppendFormat("{0}", MissionName); | ||||||
|         if (influence != "") { |         if (influence != "") { | ||||||
|  | |||||||
| @ -231,7 +231,7 @@ public class Report { | |||||||
|                 MissionCompletedEntry? completed = e as MissionCompletedEntry; |                 MissionCompletedEntry? completed = e as MissionCompletedEntry; | ||||||
| 
 | 
 | ||||||
|                 if (completed == null || |                 if (completed == null || | ||||||
|                     completed.MissionID == null) { |                     completed.Mission == null) { | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
| @ -240,48 +240,38 @@ public class Report { | |||||||
|                 ulong accepted_address; |                 ulong accepted_address; | ||||||
|                 string? accepted_system; |                 string? accepted_system; | ||||||
| 
 | 
 | ||||||
|                 string? target_faction_name = completed.TargetFaction; |                 string? target_faction_name = completed.Mission.TargetFaction; | ||||||
|                 string? source_faction_name = completed.Faction; |                 string? source_faction_name = completed.Mission.Faction; | ||||||
| 
 | 
 | ||||||
|                 if (!acceptedMissions.TryGetValue(completed.MissionID.Value, out accepted)) { |                 if (!acceptedMissions.TryGetValue(completed.Mission.MissionID, out accepted)) { | ||||||
|                     OnLog?.Invoke(string.Format( |                     OnLog?.Invoke(string.Format( | ||||||
|                         "Unable to find mission acceptance for mission \"{0}\". " + |                         "Unable to find mission acceptance for mission \"{0}\". " + | ||||||
|                         "Please extend range to include the mission acceptance.", completed.HumanReadableName |                         "Please extend range to include the mission acceptance.", completed.Mission.LocalisedName | ||||||
|                         )); |                         )); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if (!acceptedSystems.TryGetValue(completed.MissionID.Value, out accepted_address)) { |                 if (!acceptedSystems.TryGetValue(completed.Mission.MissionID, out accepted_address)) { | ||||||
|                     OnLog?.Invoke(string.Format( |                     OnLog?.Invoke(string.Format( | ||||||
|                         "Unable to figure out in which system mission \"{0}\" was accepted.", completed.HumanReadableName |                         "Unable to figure out in which system mission \"{0}\" was accepted.", completed.Mission.LocalisedName | ||||||
|                         )); |                         )); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if (!systems.TryGetValue(accepted_address, out accepted_system)) { |                 if (!systems.TryGetValue(accepted_address, out accepted_system)) { | ||||||
|                     OnLog?.Invoke(string.Format( |                     OnLog?.Invoke(string.Format( | ||||||
|                         "Unable to figure out in which system mission \"{0}\" was accepted.", completed.HumanReadableName |                         "Unable to figure out in which system mission \"{0}\" was accepted.", completed.Mission.LocalisedName | ||||||
|                         )); |                         )); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if (completed.HumanReadableNameWasGenerated) { |                 foreach (var other in completed.Mission.Influences) { | ||||||
|                     /* If the human readable name was generated, we send a log message. Because the |  | ||||||
|                      * generated names all sort of suck, we should have more human readable names in |  | ||||||
|                      * in the lookup dictionary. |  | ||||||
|                      */ |  | ||||||
|                     OnLog?.Invoke("Human readable name for mission \"" + |  | ||||||
|                         completed.Name + |  | ||||||
|                         "\" was generated, please report this."); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 foreach (var other in completed.Influences) { |  | ||||||
|                     string faction = other.Key; |                     string faction = other.Key; | ||||||
|                     if (string.IsNullOrEmpty(faction)) { |                     if (string.IsNullOrEmpty(faction)) { | ||||||
|                         OnLog?.Invoke(string.Format( |                         OnLog?.Invoke(string.Format( | ||||||
|                             "Mission \"{0}\" has empty faction name in influence block, "+ |                             "Mission \"{0}\" has empty faction name in influence block, "+ | ||||||
|                             "so this influence support was ignored. " + |                             "so this influence support was ignored. " + | ||||||
|                             "Please check the README on why this happens.", completed.HumanReadableName) |                             "Please check the README on why this happens.", completed.Mission.LocalisedName) | ||||||
|                             ); |                             ); | ||||||
|                         continue; |                         continue; | ||||||
|                     } |                     } | ||||||
| @ -294,7 +284,7 @@ public class Report { | |||||||
|                             "Mission \"{0}\" gave no influence to \"{1}\", so we assume this is because the " + |                             "Mission \"{0}\" gave no influence to \"{1}\", so we assume this is because the " + | ||||||
|                             "faction is in a conflict and cannot gain influence right now. " + |                             "faction is in a conflict and cannot gain influence right now. " + | ||||||
|                             "If this assessment is wrong, just remove the entry from the objective list.", |                             "If this assessment is wrong, just remove the entry from the objective list.", | ||||||
|                             completed.HumanReadableName, faction |                             completed.Mission.LocalisedName, faction | ||||||
|                             )); |                             )); | ||||||
| 
 | 
 | ||||||
|                         if (string.Compare(target_faction_name, faction, true) == 0) { |                         if (string.Compare(target_faction_name, faction, true) == 0) { | ||||||
| @ -310,7 +300,7 @@ public class Report { | |||||||
|                                 "Mission \"{0}\" gave no influence to \"{1}\". Since \"{1}\" is the target faction " + |                                 "Mission \"{0}\" gave no influence to \"{1}\". Since \"{1}\" is the target faction " + | ||||||
|                                 "of the mission, we assume the influence was gained in \"{2}\". " + |                                 "of the mission, we assume the influence was gained in \"{2}\". " + | ||||||
|                                 "Please remove the entry if this assumption is wrong.", |                                 "Please remove the entry if this assumption is wrong.", | ||||||
|                                 completed.HumanReadableName, faction, current_system |                                 completed.Mission.LocalisedName, faction, current_system | ||||||
|                                 )); |                                 )); | ||||||
|                         } else if (string.Compare(source_faction_name, faction, true) == 0) { |                         } else if (string.Compare(source_faction_name, faction, true) == 0) { | ||||||
|                             /* source faction of the mission is not getting any influence. This could be because |                             /* source faction of the mission is not getting any influence. This could be because | ||||||
| @ -324,7 +314,7 @@ public class Report { | |||||||
|                                 "Mission \"{0}\" gave no influence to \"{1}\". Since \"{1}\" is the source faction " + |                                 "Mission \"{0}\" gave no influence to \"{1}\". Since \"{1}\" is the source faction " + | ||||||
|                                 "of the mission, we assume the influence was gained in \"{2}\". " + |                                 "of the mission, we assume the influence was gained in \"{2}\". " + | ||||||
|                                 "Please remove the entry if this assumption is wrong.", |                                 "Please remove the entry if this assumption is wrong.", | ||||||
|                                 completed.HumanReadableName, faction, accepted_system |                                 completed.Mission.LocalisedName, faction, accepted_system | ||||||
|                                 )); |                                 )); | ||||||
| 
 | 
 | ||||||
|                             /* check if source/target faction are equal, in which case we also need an entry |                             /* check if source/target faction are equal, in which case we also need an entry | ||||||
| @ -338,7 +328,7 @@ public class Report { | |||||||
|                                     "Mission \"{0}\" gave no influence to \"{1}\". Since \"{1}\" is the source and target faction " + |                                     "Mission \"{0}\" gave no influence to \"{1}\". Since \"{1}\" is the source and target faction " + | ||||||
|                                     "of the mission, we assume the influence was also gained in target system \"{2}\". " + |                                     "of the mission, we assume the influence was also gained in target system \"{2}\". " + | ||||||
|                                     "Please remove the entry if this assumption is wrong.", |                                     "Please remove the entry if this assumption is wrong.", | ||||||
|                                     completed.HumanReadableName, faction, current_system |                                     completed.Mission.LocalisedName, faction, current_system | ||||||
|                                     )); |                                     )); | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
| @ -349,7 +339,7 @@ public class Report { | |||||||
|                         string? system; |                         string? system; | ||||||
|                         string? accepted_station; |                         string? accepted_station; | ||||||
| 
 | 
 | ||||||
|                         if (completed.MissionID == null) { |                         if (completed.Mission == null) { | ||||||
|                             continue; |                             continue; | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| @ -360,9 +350,9 @@ public class Report { | |||||||
|                             continue; |                             continue; | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
|                         if (!acceptedStations.TryGetValue(completed.MissionID.Value, out accepted_station)) { |                         if (!acceptedStations.TryGetValue(completed.Mission.MissionID, out accepted_station)) { | ||||||
|                             OnLog?.Invoke(string.Format( |                             OnLog?.Invoke(string.Format( | ||||||
|                                 "Unable to figure out in which station mission \"{0}\" was accepted.", completed.HumanReadableName |                                 "Unable to figure out in which station mission \"{0}\" was accepted.", completed.Mission.LocalisedName | ||||||
|                                 )); |                                 )); | ||||||
|                             continue; |                             continue; | ||||||
|                         } |                         } | ||||||
|  | |||||||
| @ -272,38 +272,34 @@ internal class MissionAcceptedParser : TransactionParserPart { | |||||||
| internal class MissionCompletedParser : TransactionParserPart { | internal class MissionCompletedParser : TransactionParserPart { | ||||||
|     public void Parse(Entry e, TransactionParserContext context, TransactionList transactions) { |     public void Parse(Entry e, TransactionParserContext context, TransactionList transactions) { | ||||||
|         MissionCompletedEntry? entry = e as MissionCompletedEntry; |         MissionCompletedEntry? entry = e as MissionCompletedEntry; | ||||||
|         if (entry == null) { |         if (entry == null || entry.Mission == null) { | ||||||
|             throw new NotImplementedException(); |             throw new NotImplementedException(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (entry.MissionID == null) { |  | ||||||
|             throw new InvalidJournalEntryException("mission completed has no mission ID"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         MissionAcceptedEntry? accepted = null; |         MissionAcceptedEntry? accepted = null; | ||||||
|         Location? accepted_location = null; |         Location? accepted_location = null; | ||||||
|         string? target_faction_name = entry.TargetFaction; |         string? target_faction_name = entry.Mission.TargetFaction; | ||||||
|         string? source_faction_name = entry.Faction; |         string? source_faction_name = entry.Mission.Faction; | ||||||
| 
 | 
 | ||||||
|         // We did not find when the mission was accepted. |         // We did not find when the mission was accepted. | ||||||
|         if (!context.AcceptedMissions.TryGetValue(entry.MissionID.Value, out accepted)) { |         if (!context.AcceptedMissions.TryGetValue(entry.Mission.MissionID, out accepted)) { | ||||||
|             transactions.AddIncomplete(new MissionCompleted(), |             transactions.AddIncomplete(new MissionCompleted(), | ||||||
|                 String.Format("Mission acceptance for mission id {0} was not found", |                 String.Format("Mission acceptance for mission id {0} was not found", | ||||||
|                 entry.MissionID.Value)); |                 entry.Mission.MissionID)); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!context.AcceptedMissionLocation.TryGetValue(entry.MissionID.Value, out accepted_location)) { |         if (!context.AcceptedMissionLocation.TryGetValue(entry.Mission.MissionID, out accepted_location)) { | ||||||
|             transactions.AddIncomplete(new MissionCompleted(), |             transactions.AddIncomplete(new MissionCompleted(), | ||||||
|                 String.Format("Location for acceptance for mission id {0} was not found", |                 String.Format("Location for acceptance for mission id {0} was not found", | ||||||
|                 entry.MissionID.Value)); |                 entry.Mission.MissionID)); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // This block does some preliminary "repairs" on the influences block of a completed |         // This block does some preliminary "repairs" on the influences block of a completed | ||||||
|         // mission. Sometimes these entries are broken, or are missing information for later |         // mission. Sometimes these entries are broken, or are missing information for later | ||||||
|         // parsing. |         // parsing. | ||||||
|         foreach (var other in entry.Influences) { |         foreach (var other in entry.Mission.Influences) { | ||||||
|             string faction = other.Key; |             string faction = other.Key; | ||||||
|             if (string.IsNullOrEmpty(faction)) { |             if (string.IsNullOrEmpty(faction)) { | ||||||
|                 // Target faction might be empty string, in special cases. For example if you |                 // Target faction might be empty string, in special cases. For example if you | ||||||
|  | |||||||
| @ -1,159 +1,9 @@ | |||||||
| using System.Collections.Generic; | namespace EDPlayerJournal.Entries; | ||||||
| using System.Text; |  | ||||||
| using System.Linq; |  | ||||||
| using Newtonsoft.Json.Linq; |  | ||||||
| 
 | 
 | ||||||
| namespace EDPlayerJournal.Entries;  |  | ||||||
| public class MissionCompletedEntry : Entry { | public class MissionCompletedEntry : Entry { | ||||||
|     public Dictionary<string, Dictionary<ulong, string>> Influences { get; set; } = new Dictionary<string, Dictionary<ulong, string>>(); |     public Mission? Mission { get; set; } | ||||||
|     private List<string> Affected { get; set; } = new List<string>(); |  | ||||||
| 
 |  | ||||||
|     private string? readable_name = null; |  | ||||||
|     private bool readable_name_generated = false; |  | ||||||
| 
 | 
 | ||||||
|     protected override void Initialise() { |     protected override void Initialise() { | ||||||
|         MissionID = JSON.Value<ulong?>("MissionID") ?? 0; |         Mission = Mission.FromMissionCompleted(JSON); | ||||||
|         Name = JSON.Value<string>("Name"); |  | ||||||
|         Faction = JSON.Value<string>("Faction") ?? ""; |  | ||||||
|         TargetFaction = JSON.Value<string>("TargetFaction") ?? ""; |  | ||||||
|         if (JSON.ContainsKey("Commodity_Localised")) { |  | ||||||
|             Commodity = JSON.Value<string>("Commodity_Localised"); |  | ||||||
|         } |  | ||||||
|         if (JSON.ContainsKey("Count")) { |  | ||||||
|             Count = JSON.Value<int>("Count"); |  | ||||||
|         } |  | ||||||
|         if (JSON.ContainsKey("Donated")) { |  | ||||||
|             Donated = JSON.Value<int>("Donated"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         MakeHumanReadableName(); |  | ||||||
|         BuildInfluenceList(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private void BuildInfluenceList() { |  | ||||||
|         Influences.Clear(); |  | ||||||
|         Affected.Clear(); |  | ||||||
| 
 |  | ||||||
|         var effects = JSON.Value<JArray>("FactionEffects"); |  | ||||||
|         if (effects == null) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         foreach (var effect in effects.Children<JObject>()) { |  | ||||||
|             string? faction = effect.Value<string>("Faction"); |  | ||||||
| 
 |  | ||||||
|             if (faction == null) { |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             Affected.Add(faction); |  | ||||||
| 
 |  | ||||||
|             var influence = effect.Value<JArray>("Influence"); |  | ||||||
|             if (influence == null || influence.Count == 0) { |  | ||||||
|                 // No influence reward, happens sometimes, but we have to accept it |  | ||||||
|                 Influences.Add(faction, new Dictionary<ulong, string>()); |  | ||||||
|             } else { |  | ||||||
|                 foreach (var infl in influence.Children<JObject>()) { |  | ||||||
|                     infl.TryGetValue("Influence", out JToken? result); |  | ||||||
|                     infl.TryGetValue("SystemAddress", out JToken? systemaddr); |  | ||||||
| 
 |  | ||||||
|                     if (result != null && result.Type == JTokenType.String && |  | ||||||
|                         systemaddr != null && systemaddr.Type == JTokenType.Integer) { |  | ||||||
|                         ulong system = systemaddr.ToObject<ulong?>() ?? 0; |  | ||||||
|                         string inf = result.ToString(); |  | ||||||
| 
 |  | ||||||
|                         if (!Influences.ContainsKey(faction)) { |  | ||||||
|                             Influences.Add(faction, new Dictionary<ulong, string>()); |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         if (!Influences[faction].ContainsKey(system)) { |  | ||||||
|                             Influences[faction].Add(system, inf); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public string? Name { get; set; } |  | ||||||
|     public string? Commodity { get; set; } |  | ||||||
|     public int? Count { get; set; } |  | ||||||
|     public int? Donated { get; set; } |  | ||||||
|     public ulong? MissionID { get; set; } |  | ||||||
|     public string? Faction { get; set; } |  | ||||||
|     public string? TargetFaction { get; set; } |  | ||||||
| 
 |  | ||||||
|     private void MakeHumanReadableName() { |  | ||||||
|         if (readable_name != null || Name == null) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         string? readable = HumanReadableMissionName.MakeHumanReadableName(Name); |  | ||||||
|         StringBuilder builder = new StringBuilder(); |  | ||||||
| 
 |  | ||||||
|         if (readable == null) { |  | ||||||
|             builder = new StringBuilder(Name); |  | ||||||
|             builder.Replace("Mission_", ""); |  | ||||||
|             builder.Replace("_name", ""); |  | ||||||
|             builder.Replace("_MB", ""); |  | ||||||
|             builder.Replace('_', ' '); |  | ||||||
|             builder.Replace("Illegal", " (Illegal)"); |  | ||||||
|             builder.Replace("OnFoot", "On Foot"); |  | ||||||
|             builder.Replace(" BS", ""); |  | ||||||
|             builder.Replace("HackMegaship", "Hack Megaship"); |  | ||||||
|             builder.Replace("Boom", ""); |  | ||||||
|             builder.Replace("RebootRestore", "Reboot/Restore"); |  | ||||||
|             builder.Replace("CivilLiberty", ""); |  | ||||||
|             readable_name_generated = true; |  | ||||||
|         } else { |  | ||||||
|             builder.Append(readable); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (Count > 0 && Commodity != null) { |  | ||||||
|             builder.AppendFormat(" ({0} {1})", Count, Commodity); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (Donated != null || Donated > 0) { |  | ||||||
|             builder.AppendFormat(" ({0})", Credits.FormatCredits(Donated ?? 0)); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         readable_name = builder.ToString().Trim(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public string? HumanReadableName { |  | ||||||
|         get { |  | ||||||
|             MakeHumanReadableName(); |  | ||||||
|             return readable_name; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public bool HumanReadableNameWasGenerated { |  | ||||||
|         get { |  | ||||||
|             MakeHumanReadableName(); |  | ||||||
|             return readable_name_generated; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public string[] AffectedFactions => Affected.ToArray(); |  | ||||||
| 
 |  | ||||||
|     public string? GetInfluenceForFaction(string faction) { |  | ||||||
|         if (Influences == null || !Influences.ContainsKey(faction)) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         var inf = Influences[faction]; |  | ||||||
|         return string.Join("", inf.Values); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public string? GetInfluenceForFaction(string faction, ulong systemaddr) { |  | ||||||
|         if (!Influences.ContainsKey(faction)) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!Influences[faction].ContainsKey(systemaddr)) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return Influences[faction][systemaddr]; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,7 +1,113 @@ | |||||||
| using Newtonsoft.Json.Linq; | using Newtonsoft.Json.Linq; | ||||||
|  | using EDPlayerJournal.Entries; | ||||||
|  | using System.Runtime.CompilerServices; | ||||||
| 
 | 
 | ||||||
| namespace EDPlayerJournal; | namespace EDPlayerJournal; | ||||||
| 
 | 
 | ||||||
|  | public class FactionEffect { | ||||||
|  |     public string? Effect { get; set; } | ||||||
|  |     public string? EffectLocalised { get; set; } | ||||||
|  |     public string? Trend { get; set; } | ||||||
|  | 
 | ||||||
|  |     public static FactionEffect FromJSON(JObject obj) { | ||||||
|  |         FactionEffect effect = new FactionEffect(); | ||||||
|  | 
 | ||||||
|  |         effect.Effect = obj.Value<string?>("Effect"); | ||||||
|  |         effect.EffectLocalised = obj.Value<string?>("Effect_Localised"); | ||||||
|  |         effect.Trend = obj.Value<string?>("Trend"); | ||||||
|  | 
 | ||||||
|  |         return effect; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public class MissionInfluence { | ||||||
|  |     /// <summary> | ||||||
|  |     /// System Address this influence happened in. | ||||||
|  |     /// </summary> | ||||||
|  |     public ulong? SystemAddress { get; set; } | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// Generic description of the trend (up or down) | ||||||
|  |     /// </summary> | ||||||
|  |     public string? Trend { get; set; } | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// Influence gained in plusses | ||||||
|  |     /// </summary> | ||||||
|  |     public string Influence { get; set; } = string.Empty; | ||||||
|  | 
 | ||||||
|  |     public static MissionInfluence FromJSON(JObject obj) { | ||||||
|  |         MissionInfluence missionInfluence = new MissionInfluence(); | ||||||
|  | 
 | ||||||
|  |         missionInfluence.SystemAddress = obj.Value<ulong?>("SystemAddress"); | ||||||
|  |         missionInfluence.Trend = obj.Value<string?>("Trend"); | ||||||
|  |         missionInfluence.Influence = obj.Value<string?>("Influence") ?? ""; | ||||||
|  | 
 | ||||||
|  |         return missionInfluence; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public class MissionFactionEffects { | ||||||
|  |     /// <summary> | ||||||
|  |     /// Faction in question | ||||||
|  |     /// </summary> | ||||||
|  |     public string? Faction { get; set; } | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// Reputation trend | ||||||
|  |     /// </summary> | ||||||
|  |     public string? ReputationTrend { get; set; } | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// Reputation in pluses. | ||||||
|  |     /// </summary> | ||||||
|  |     public string Reputation { get; set; } = string.Empty; | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// List of economic and security affects. | ||||||
|  |     /// </summary> | ||||||
|  |     public List<FactionEffect> Effects { get; set; } = new List<FactionEffect>(); | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// Influence gained. | ||||||
|  |     /// </summary> | ||||||
|  |     public List<MissionInfluence> Influences { get; set; } = new List<MissionInfluence>(); | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// Whether this affect is for an empty, or non-existant faction. | ||||||
|  |     /// </summary> | ||||||
|  |     public bool IsEmptyFaction { | ||||||
|  |         get { return string.IsNullOrEmpty(Faction); } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static MissionFactionEffects FromJSON(JObject j) { | ||||||
|  |         MissionFactionEffects o = new MissionFactionEffects(); | ||||||
|  | 
 | ||||||
|  |         o.Faction = j.Value<string>("Faction"); | ||||||
|  | 
 | ||||||
|  |         o.ReputationTrend = j.Value<string?>("ReputationTrend"); | ||||||
|  |         o.Reputation = j.Value<string?>("Reputation") ?? string.Empty; | ||||||
|  | 
 | ||||||
|  |         JArray? effects = j.Value<JArray?>("Effects"); | ||||||
|  |         if (effects != null) { | ||||||
|  |             foreach (JObject effect in effects.Children().OfType<JObject>()) { | ||||||
|  |                 FactionEffect e = FactionEffect.FromJSON(effect); | ||||||
|  |                 o.Effects.Add(e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         JArray? influences = j.Value<JArray?>("Influence"); | ||||||
|  |         if (influences != null) { | ||||||
|  |             foreach (JObject influence in influences.Children().OfType<JObject>()) { | ||||||
|  |                 MissionInfluence missionInfluence = MissionInfluence.FromJSON(influence); | ||||||
|  |                 o.Influences.Add(missionInfluence); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return o; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| public class Mission : IComparable<Mission> { | public class Mission : IComparable<Mission> { | ||||||
|     public ulong MissionID { get; set; } = 0; |     public ulong MissionID { get; set; } = 0; | ||||||
| 
 | 
 | ||||||
| @ -134,6 +240,11 @@ public class Mission : IComparable<Mission> { | |||||||
|     /// </summary> |     /// </summary> | ||||||
|     public string? PassengerType { get; set; } |     public string? PassengerType { get; set; } | ||||||
| 
 | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// Affect this mission had on factions. | ||||||
|  |     /// </summary> | ||||||
|  |     public List<MissionFactionEffects> FactionEffects { get; set; } = new List<MissionFactionEffects>(); | ||||||
|  | 
 | ||||||
|     public int CompareTo(Mission? other) { |     public int CompareTo(Mission? other) { | ||||||
|         if (other == null) { |         if (other == null) { | ||||||
|             return 1; |             return 1; | ||||||
| @ -169,6 +280,7 @@ public class Mission : IComparable<Mission> { | |||||||
|         mission.LocalisedName = o.Value<string>("LocalisedName"); |         mission.LocalisedName = o.Value<string>("LocalisedName"); | ||||||
| 
 | 
 | ||||||
|         mission.Faction = o.Value<string?>("Faction"); |         mission.Faction = o.Value<string?>("Faction"); | ||||||
|  |         mission.TargetFaction = o.Value<string?>("TargetFaction"); | ||||||
| 
 | 
 | ||||||
|         mission.Donation = o.Value<ulong?>("Donation"); |         mission.Donation = o.Value<ulong?>("Donation"); | ||||||
|         mission.Donated = o.Value<ulong?>("Donated"); |         mission.Donated = o.Value<ulong?>("Donated"); | ||||||
| @ -180,9 +292,65 @@ public class Mission : IComparable<Mission> { | |||||||
| 
 | 
 | ||||||
|         mission.KillCount = o.Value<ulong?>("KillCount"); |         mission.KillCount = o.Value<ulong?>("KillCount"); | ||||||
| 
 | 
 | ||||||
|  |         JArray? factionEffects = o.Value<JArray?>("FactionEffects"); | ||||||
|  |         if (factionEffects != null) { | ||||||
|  |             foreach (JObject effect in factionEffects.Children().OfType<JObject>()) { | ||||||
|  |                 MissionFactionEffects factionEffect = MissionFactionEffects.FromJSON(effect); | ||||||
|  |                 mission.FactionEffects.Add(factionEffect); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         return mission; |         return mission; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// Returns a list of all affected factions. | ||||||
|  |     /// </summary> | ||||||
|  |     public string[] AffectedFactions { | ||||||
|  |         get { | ||||||
|  |             return FactionEffects | ||||||
|  |                 .Where(x => !string.IsNullOrEmpty(x.Faction)) | ||||||
|  |                 .Select(x => (x.Faction ?? string.Empty)) | ||||||
|  |                 .ToArray() | ||||||
|  |                 ; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// Returns the influence for a given faction in a given star system. | ||||||
|  |     /// </summary> | ||||||
|  |     /// <param name="faction">Faction name in question.</param> | ||||||
|  |     /// <param name="systemaddr">Star System address</param> | ||||||
|  |     /// <returns>null if no entry was found, or a string denoting pluses for the amount influence gained.</returns> | ||||||
|  |     public string? GetInfluenceForFaction(string faction, ulong systemaddr) { | ||||||
|  |         var results = FactionEffects | ||||||
|  |             .Where(x => string.Compare(x.Faction, faction) == 0) | ||||||
|  |             .SelectMany(x => x.Influences) | ||||||
|  |             .Where(x => (x.SystemAddress != null && x.SystemAddress == systemaddr)) | ||||||
|  |             .Select(x => x.Influence) | ||||||
|  |             .ToArray() | ||||||
|  |             ; | ||||||
|  | 
 | ||||||
|  |         if (results == null || results.Length == 0) { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return string.Join("", results); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Dictionary<string, Dictionary<ulong, string>> Influences { | ||||||
|  |         get { | ||||||
|  |             return FactionEffects | ||||||
|  |                 .Where(x => x.Faction != null) | ||||||
|  |                 .ToDictionary( | ||||||
|  |                     x => (x.Faction ?? string.Empty), | ||||||
|  |                     x => x.Influences | ||||||
|  |                             .Where(x => x.SystemAddress != null) | ||||||
|  |                             .ToDictionary(x => (x.SystemAddress ?? 0), x => x.Influence) | ||||||
|  |                     ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public static Mission FromMissionAccepted(JObject o) { |     public static Mission FromMissionAccepted(JObject o) { | ||||||
|         return FromJSON(o); |         return FromJSON(o); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1,9 +1,6 @@ | |||||||
| using System; | using EDPlayerJournal; | ||||||
| using System.Collections.Generic; |  | ||||||
| using System.Linq; |  | ||||||
| using System.Text; |  | ||||||
| using System.Threading.Tasks; |  | ||||||
| using EDPlayerJournal.Entries; | using EDPlayerJournal.Entries; | ||||||
|  | using System.Diagnostics.Metrics; | ||||||
| 
 | 
 | ||||||
| namespace EDPlayerJournalTests; | namespace EDPlayerJournalTests; | ||||||
| 
 | 
 | ||||||
| @ -24,14 +21,101 @@ public class MissionTest { | |||||||
|         Assert.IsNotNull(accepted); |         Assert.IsNotNull(accepted); | ||||||
|         Assert.IsNotNull(accepted.Mission); |         Assert.IsNotNull(accepted.Mission); | ||||||
| 
 | 
 | ||||||
|         Assert.AreEqual(accepted.Mission.MissionID, (ulong)901601358); |         Assert.AreEqual(accepted.Mission.MissionID, 901601358UL); | ||||||
|         Assert.AreEqual(accepted.Mission.Faction, "HIP 6182 Federal Inc"); |         Assert.AreEqual(accepted.Mission.Faction, "HIP 6182 Federal Inc"); | ||||||
|         Assert.AreEqual(accepted.Mission.Name, "Mission_AltruismCredits"); |         Assert.AreEqual(accepted.Mission.Name, "Mission_AltruismCredits"); | ||||||
|         Assert.AreEqual(accepted.Mission.LocalisedName, "Donate 1,000,000 Cr to the cause"); |         Assert.AreEqual(accepted.Mission.LocalisedName, "Donate 1,000,000 Cr to the cause"); | ||||||
|         Assert.AreEqual(accepted.Mission.Donation, (ulong)1000000); |         Assert.AreEqual(accepted.Mission.Donation, 1000000UL); | ||||||
|         Assert.AreEqual(accepted.Mission.Expiry, "2022-11-23T11:50:52Z"); |         Assert.AreEqual(accepted.Mission.Expiry, "2022-11-23T11:50:52Z"); | ||||||
|         Assert.AreEqual(accepted.Mission.Wing, false); |         Assert.AreEqual(accepted.Mission.Wing, false); | ||||||
|         Assert.AreEqual(accepted.Mission.Reputation, "++"); |         Assert.AreEqual(accepted.Mission.Reputation, "++"); | ||||||
|         Assert.AreEqual(accepted.Mission.Influence, "++"); |         Assert.AreEqual(accepted.Mission.Influence, "++"); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     [TestMethod] | ||||||
|  |     public void NoInfluence() { | ||||||
|  |         string noinfluence = """{ "timestamp":"2022-02-24T19:42:38Z", "event":"MissionCompleted", "Faction":"Social LHS 6103 Confederation", "Name":"Mission_Hack_BLOPS_Elections_name", "MissionID":849749964, "NewDestinationSystem":"Dewikum", "DestinationSystem":"LF 8 +16 41", "Target":"$MissionUtil_Settlement_Target_PostBox;", "Target_Localised":"Hub Access Terminal", "Reward":14266, "FactionEffects":[ { "Faction":"", "Effects":[ { "Effect":"$MISSIONUTIL_Interaction_Summary_EP_down;", "Effect_Localised":"The economic status of $#MinorFaction; has declined in the $#System; system.", "Trend":"DownBad" } ], "Influence":[ { "SystemAddress":251012319587, "Trend":"DownBad", "Influence":"+" } ], "ReputationTrend":"DownBad", "Reputation":"+" }, { "Faction":"Social LHS 6103 Confederation", "Effects":[  ], "Influence":[  ], "ReputationTrend":"UpGood", "Reputation":"+" } ] }"""; | ||||||
|  | 
 | ||||||
|  |         Entry? entry = Entry.Parse(noinfluence); | ||||||
|  | 
 | ||||||
|  |         Assert.IsNotNull(entry); | ||||||
|  |         Assert.IsInstanceOfType(entry, typeof(MissionCompletedEntry)); | ||||||
|  | 
 | ||||||
|  |         MissionCompletedEntry? completed = entry as MissionCompletedEntry; | ||||||
|  | 
 | ||||||
|  |         Assert.IsNotNull(completed); | ||||||
|  |         Assert.IsNotNull(completed.Mission); | ||||||
|  | 
 | ||||||
|  |         Mission m = completed.Mission; | ||||||
|  | 
 | ||||||
|  |         Assert.AreEqual(m.FactionEffects.Count, 2); | ||||||
|  | 
 | ||||||
|  |         // Empty faction should not count towards affected factions | ||||||
|  |         Assert.AreEqual(m.AffectedFactions.Length, 1); | ||||||
|  | 
 | ||||||
|  |         MissionFactionEffects e; | ||||||
|  |          | ||||||
|  |         e = m.FactionEffects[0]; | ||||||
|  |         Assert.IsTrue(e.IsEmptyFaction); | ||||||
|  |         Assert.AreEqual(e.Faction, string.Empty); | ||||||
|  | 
 | ||||||
|  |         string? influence = m.GetInfluenceForFaction("", 251012319587UL); | ||||||
|  |         Assert.IsNotNull(influence); | ||||||
|  |         Assert.AreEqual(influence, "+"); | ||||||
|  | 
 | ||||||
|  |         e = m.FactionEffects[1]; | ||||||
|  |         Assert.AreEqual(e.Faction, "Social LHS 6103 Confederation"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     [TestMethod] | ||||||
|  |     public void TestMissionCompleted() { | ||||||
|  |         string courier = /*lang=json,strict*/ """{ "timestamp":"2022-11-21T16:14:33Z", "event":"MissionCompleted", "Faction":"Salus Imperial Society", "Name":"Mission_Courier_Elections_name", "MissionID":901326396, "TargetFaction":"Salus Imperial Society", "DestinationSystem":"Saelishi", "DestinationStation":"Serrao Arsenal", "Reward":87404, "FactionEffects":[ { "Faction":"Salus Imperial Society", "Effects":[ { "Effect":"$MISSIONUTIL_Interaction_Summary_EP_up;", "Effect_Localised":"The economic status of $#MinorFaction; has improved in the $#System; system.", "Trend":"UpGood" }, { "Effect":"$MISSIONUTIL_Interaction_Summary_EP_up;", "Effect_Localised":"The economic status of $#MinorFaction; has improved in the $#System; system.", "Trend":"UpGood" } ], "Influence":[ { "SystemAddress":1865919973739, "Trend":"UpGood", "Influence":"++" }, { "SystemAddress":1733186884306, "Trend":"UpGood", "Influence":"++" } ], "ReputationTrend":"UpGood", "Reputation":"++" } ] }"""; | ||||||
|  | 
 | ||||||
|  |         Entry? entry = Entry.Parse(courier); | ||||||
|  | 
 | ||||||
|  |         Assert.IsNotNull(entry); | ||||||
|  |         Assert.IsInstanceOfType(entry, typeof(MissionCompletedEntry)); | ||||||
|  | 
 | ||||||
|  |         MissionCompletedEntry? completed = entry as MissionCompletedEntry; | ||||||
|  | 
 | ||||||
|  |         Assert.IsNotNull(completed); | ||||||
|  |         Assert.IsNotNull(completed.Mission); | ||||||
|  | 
 | ||||||
|  |         Mission m = completed.Mission; | ||||||
|  | 
 | ||||||
|  |         Assert.AreEqual(m.Faction, "Salus Imperial Society"); | ||||||
|  |         Assert.AreEqual(m.Name, "Mission_Courier_Elections_name"); | ||||||
|  |         Assert.AreEqual(m.MissionID, 901326396UL); | ||||||
|  |         Assert.AreEqual(m.TargetFaction, "Salus Imperial Society"); | ||||||
|  |         Assert.AreEqual(m.DestinationSystem, "Saelishi"); | ||||||
|  |         Assert.AreEqual(m.DestinationStation, "Serrao Arsenal"); | ||||||
|  |         Assert.IsNull(m.DestinationSettlement); | ||||||
|  |         Assert.AreEqual(m.Reward, 87404UL); | ||||||
|  | 
 | ||||||
|  |         Assert.AreEqual(m.FactionEffects.Count, 1); | ||||||
|  | 
 | ||||||
|  |         var effect = m.FactionEffects[0]; | ||||||
|  | 
 | ||||||
|  |         Assert.AreEqual(effect.Influences.Count, 2); | ||||||
|  |         Assert.AreEqual(effect.Effects.Count, 2); | ||||||
|  | 
 | ||||||
|  |         Assert.AreEqual(effect.Reputation, "++"); | ||||||
|  | 
 | ||||||
|  |         string? influence; | ||||||
|  | 
 | ||||||
|  |         influence = m.GetInfluenceForFaction("Salus Imperial Society", 1865919973739UL); | ||||||
|  |         Assert.AreEqual(influence, "++"); | ||||||
|  | 
 | ||||||
|  |         influence = m.GetInfluenceForFaction("Salus Imperial Society", 1733186884306UL); | ||||||
|  |         Assert.AreEqual(influence, "++"); | ||||||
|  | 
 | ||||||
|  |         influence = m.GetInfluenceForFaction("Saelishi Saxons", 1733186884306UL); | ||||||
|  |         Assert.IsNull(influence); | ||||||
|  | 
 | ||||||
|  |         // Only one entry are we only have Salus | ||||||
|  |         Assert.AreEqual(m.Influences.Count, 1); | ||||||
|  |         Assert.AreEqual(m.Influences["Salus Imperial Society"].Count, 2); | ||||||
|  |         Assert.AreEqual(m.Influences["Salus Imperial Society"][1865919973739UL], "++"); | ||||||
|  |         Assert.AreEqual(m.Influences["Salus Imperial Society"][1733186884306UL], "++"); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -7,28 +7,23 @@ namespace EDPlayerJournalTests; | |||||||
| [TestClass] | [TestClass] | ||||||
| public class TestTransactionParser { | public class TestTransactionParser { | ||||||
|     private List<Entry>? LoadTestData(string filename) { |     private List<Entry>? LoadTestData(string filename) { | ||||||
|         try { |         string path = Path.GetFullPath("./" + filename); | ||||||
|             string path = Path.GetFullPath("./" + filename); |         string[] lines = File.ReadAllLines(path); | ||||||
|             string[] lines = File.ReadAllLines(path); |         List<Entry> entries = new(); | ||||||
|             List<Entry> entries = new(); |  | ||||||
| 
 | 
 | ||||||
|             foreach (string line in lines) { |         foreach (string line in lines) { | ||||||
|                 line.Trim(); |             line.Trim(); | ||||||
|                 if (string.IsNullOrEmpty(line)) { |             if (string.IsNullOrEmpty(line)) { | ||||||
|                     continue; |                 continue; | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 Entry? entry = Entry.Parse(line); |  | ||||||
|                 if (entry != null) { |  | ||||||
|                     entries.Add(entry); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return entries; |             Entry? entry = Entry.Parse(line); | ||||||
|         } catch (Exception) { |             if (entry != null) { | ||||||
|  |                 entries.Add(entry); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return null; |         return entries; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     [TestMethod] |     [TestMethod] | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user