Skip to content

Commit

Permalink
Merge branch 'feature/2621-cargo-transfer-event' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Tkael committed Jun 24, 2024
2 parents b230fae + 2d740aa commit b6ae82b
Show file tree
Hide file tree
Showing 14 changed files with 206 additions and 16 deletions.
36 changes: 36 additions & 0 deletions Events/CargoTransferEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using EddiDataDefinitions;
using System;
using System.Collections.Generic;
using Utilities;

namespace EddiEvents
{
[PublicAPI]
public class CargoTransferEvent : Event
{
public const string NAME = "Cargo transfer";
public const string DESCRIPTION = "Triggered when transferring commodities between your ship, SRV, or carrier";
public static readonly string[] SAMPLES =
{
@"{ ""timestamp"":""2023-06-09T09:18:40Z"", ""event"":""CargoTransfer"", ""Transfers"":[ { ""Type"":""thargoidgeneratortissuesample"", ""Type_Localised"":""Caustic Tissue Sample"", ""Count"":2, ""Direction"":""tocarrier"" }, { ""Type"":""drones"", ""Type_Localised"":""Limpet"", ""Count"":12, ""Direction"":""toship"" } ] }",
@"{ ""timestamp"":""2023-05-22T08:36:19Z"", ""event"":""CargoTransfer"", ""Transfers"":[ { ""Type"":""radiationbaffle"", ""Type_Localised"":""Radiation Baffle"", ""Count"":46, ""Direction"":""tocarrier"" }, { ""Type"":""metaalloys"", ""Type_Localised"":""Meta-Alloys"", ""Count"":16, ""Direction"":""toship"" }, { ""Type"":""neofabricinsulation"", ""Type_Localised"":""Neofabric Insulation"", ""Count"":12, ""Direction"":""toship"" } ] }",
@"{ ""timestamp"":""2022-08-20T22:11:41Z"", ""event"":""CargoTransfer"", ""Transfers"":[ { ""Type"":""unknownartifact3"", ""Type_Localised"":""Thargoid Link"", ""Count"":1, ""Direction"":""toship"" }, { ""Type"":""ancientrelic"", ""Type_Localised"":""Guardian Relic"", ""Count"":3, ""Direction"":""toship"" }, { ""Type"":""unknowntechnologysamples"", ""Type_Localised"":""Thargoid Technology Samples"", ""Count"":1, ""Direction"":""tosrv"" } ] }"
};

[PublicAPI("The commodities and amounts being transferred to your ship")]
public List<CommodityAmount> toship { get; private set; }

[PublicAPI( "The commodities and amounts being transferred to your SRV" )]
public List<CommodityAmount> tosrv { get; private set; }

[PublicAPI( "The commodities and amounts being transferred to your carrier" )]
public List<CommodityAmount> tocarrier { get; private set; }

public CargoTransferEvent ( DateTime timestamp, List<CommodityAmount> toShip, List<CommodityAmount> toSRV, List<CommodityAmount> toCarrier ) : base(timestamp, NAME)
{
this.toship = toShip;
this.tosrv = toSRV;
this.tocarrier = toCarrier;
}
}
}
72 changes: 68 additions & 4 deletions JournalMonitor/JournalMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
Expand All @@ -20,13 +21,18 @@ namespace EddiJournalMonitor
{
public class JournalMonitor : LogMonitor, IEddiMonitor
{
private static readonly Regex JsonRegex = new Regex( @"^{.*}$", RegexOptions.Singleline );

public JournalMonitor () : base( GetSavedGamesDir(), @"^Journal.*\.[0-9\.]+\.log$",
( result, isLogLoadEvent ) =>
ForwardJournalEntries( result.ToList(), EDDI.Instance.enqueueEvent, isLogLoadEvent ) )
{ }

private static readonly Regex JsonRegex = new Regex( @"^{.*}$", RegexOptions.Singleline );

/// <summary>
/// Holds a delayed event until we see an event of the type specified
/// </summary>
private static readonly ConcurrentDictionary<string, Event> DelayedEventHolder = new ConcurrentDictionary<string, Event>();

private enum ShipyardType { [UsedImplicitly] ShipsHere, [UsedImplicitly] ShipsRemote }

private static readonly Dictionary<long, CancellationTokenSource> carrierJumpCancellationTokenSources =
Expand All @@ -40,6 +46,15 @@ private static void ForwardJournalEntries ( IList<string> lines, Action<Event> c

var events = ParseJournalEntries(lines, isLogLoadEventBatch);

// Append any delayed events
foreach ( var @event in events.ToList() )
{
if ( DelayedEventHolder.TryGetValue( @event.type, out var delayedEvent ) )
{
events.Add( delayedEvent );
}
}

// Enqueue events for processing
events.ForEach(callback);
}
Expand Down Expand Up @@ -104,7 +119,7 @@ public static List<Event> ParseJournalEntries(IList<string> lines, bool fromLogL
return events;
}

public static List<Event> ParseJournalEntry(string line, bool fromLogLoad = false)
public static List<Event> ParseJournalEntry(string line, bool fromLogLoad = false, bool fromSpeechResponderTest = false )
{
List<Event> events = new List<Event>();
try
Expand Down Expand Up @@ -5023,6 +5038,56 @@ MicroResource GetResource( IDictionary<string, object> resourceData )
}
handled = true;
break;
case "CargoTransfer": // Could use for cargo transfers between ship and fleet carrier; the `Cargo` event already keeps ship and SRV cargo up to date.
{
var toShip = new List<CommodityAmount>();
var toSRV = new List<CommodityAmount>();
var toCarrier = new List<CommodityAmount>();
if ( data.TryGetValue("Transfers", out var transfersVal) )
{
var transfersArray = JArray.FromObject( transfersVal );
foreach ( var transfer in transfersArray )
{
var direction = transfer[ "Direction" ].ToString();
var count = (int)transfer[ "Count" ];
var commodity = CommodityDefinition.FromEDName( transfer[ "Type" ].ToString() );
commodity.fallbackLocalizedName = transfer[ "Type_Localised" ]?.ToString();

// Objects may have a `MissionID` but the legalstatus is not identified so we rtat these items
// as CommodityAmount objects and use the `Cargo` event to update the CargoMonitor.

var commodityAmount = new CommodityAmount( commodity, count );
if ( direction.Equals( "toship", StringComparison.InvariantCultureIgnoreCase ) )
{
toShip.Add( commodityAmount );
}
else if ( direction.Equals( "tosrv", StringComparison.InvariantCultureIgnoreCase ) )
{
toSRV.Add( commodityAmount );
}
else if ( direction.Equals( "tocarrier", StringComparison.InvariantCultureIgnoreCase ) )
{
toCarrier.Add( commodityAmount );
}
else
{
throw new ArgumentException( "Unhandled CargoTransfer `Direction`." );
}
}
}

var cargoTransferEvent = new CargoTransferEvent( timestamp, toShip, toSRV, toCarrier ) { raw = line, fromLoad = fromLogLoad };
if ( fromSpeechResponderTest )
{
events.Add( cargoTransferEvent );
}
else
{
DelayedEventHolder[ CargoEvent.NAME ] = cargoTransferEvent;
}
}
handled = true;
break;

// we silently ignore these, but forward them to the responders
case "CodexDiscovery":
Expand All @@ -5036,7 +5101,6 @@ MicroResource GetResource( IDictionary<string, object> resourceData )
// Low priority (for now)
case "BuyWeapon":
case "CarrierTradeOrder": // Implement when we are ready to handle fleet carrier cargo.
case "CargoTransfer": // Could use for cargo transfers between ship and fleet carrier; the `Cargo` event already keeps ship and SRV cargo up to date.
case "CarrierModulePack":
case "CarrierShipPack":
case "ClearImpound": // Sample: { "timestamp":"2022-10-20T18:01:17Z", "event":"ClearImpound", "ShipType":"asp", "ShipType_Localised":"Asp Explorer", "ShipID":34, "ShipMarketID":3705689344, "MarketID":3705689344 }
Expand Down
22 changes: 11 additions & 11 deletions SpeechResponder/EddiSpeechResponder.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,37 +41,37 @@
<ItemGroup>
<EmbeddedResource Include="AvalonEdit\Cottle.xshd" />
<None Update="eddi.cs.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="eddi.de.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="eddi.es.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="eddi.fr.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="eddi.hu.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="eddi.it.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="eddi.ja.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="eddi.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="eddi.pt-BR.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="eddi.ru.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="eddi.zh-CN.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="SpeechResponderHelp.md">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
Expand Down
2 changes: 1 addition & 1 deletion SpeechResponder/SpeechResponder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public void TestScript(string scriptName, Dictionary<string, Script> scripts)
else if (sample is string s)
{
// It's a string so a journal entry. Parse it
sampleEvents = JournalMonitor.ParseJournalEntry(s);
sampleEvents = JournalMonitor.ParseJournalEntry(s, false, true);
}
else if (sample is Event e)
{
Expand Down
9 changes: 9 additions & 0 deletions SpeechResponder/eddi.cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@
"name": "Cargo scoop",
"description": "Triggered when you deploy or retract your cargo scoop"
},
"Cargo transfer": {
"enabled": true,
"priority": 3,
"responder": true,
"script": "{_ Set up a simple function to create descriptions for each transferred commodity }\r\n\r\n{set parseItem(cargo) to:\r\n {if cargo.amount = 1: \r\n {set tonnes to \" tonne \"}\r\n |else: \r\n {set tonnes to \" tonnes \"}\r\n }\r\n {set item to cat(cargo.amount, tonnes, \" of \", cargo.commodity)}\r\n {return item}\r\n}\r\n\r\n{_ Generate lists of transfer descriptions for each of the possible locations }\r\n\r\n{if len(event.toship) > 0:\r\n {set toShip to []}\r\n {for cargo in event.toship:\r\n {set toShip to cat(toShip, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{if len(event.tocarrier) > 0:\r\n {set toCarrier to []}\r\n {for cargo in event.tocarrier:\r\n {set toCarrier to cat(toCarrier, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{if len(event.tosrv) > 0:\r\n {set toSRV to []}\r\n {for cargo in event.tosrv:\r\n {set toSRV to cat(toSRV, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{_ Begin speaking }\r\n\r\nYou have transferred\r\n\r\n{if len(toShip) > 0:\r\n {List(toShip)} to {OneOf(ShipName(), \"your ship\")}\r\n}\r\n\r\n{if len(toCarrier) > 0:\r\n {if len(toShip) > 0: and }\r\n {List(toCarrier)} to {OneOf(carrier.name, \"your carrier\")}\r\n}\r\n\r\n{if len(toSRV) > 0:\r\n {if len(toShip) > 0: and }\r\n {List(toSRV)} to your SRV\r\n}.\r\n",
"default": true,
"name": "Cargo transfer",
"description": "Triggered when transferring commodities between your ship, SRV, or carrier"
},
"Cargo wingupdate": {
"enabled": true,
"priority": 3,
Expand Down
9 changes: 9 additions & 0 deletions SpeechResponder/eddi.de.json
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@
"name": "Cargo scoop",
"description": "Triggered when you deploy or retract your cargo scoop"
},
"Cargo transfer": {
"enabled": true,
"priority": 3,
"responder": true,
"script": "{_ Set up a simple function to create descriptions for each transferred commodity }\r\n\r\n{set parseItem(cargo) to:\r\n {if cargo.amount = 1: \r\n {set tonnes to \" tonne \"}\r\n |else: \r\n {set tonnes to \" tonnes \"}\r\n }\r\n {set item to cat(cargo.amount, tonnes, \" of \", cargo.commodity)}\r\n {return item}\r\n}\r\n\r\n{_ Generate lists of transfer descriptions for each of the possible locations }\r\n\r\n{if len(event.toship) > 0:\r\n {set toShip to []}\r\n {for cargo in event.toship:\r\n {set toShip to cat(toShip, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{if len(event.tocarrier) > 0:\r\n {set toCarrier to []}\r\n {for cargo in event.tocarrier:\r\n {set toCarrier to cat(toCarrier, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{if len(event.tosrv) > 0:\r\n {set toSRV to []}\r\n {for cargo in event.tosrv:\r\n {set toSRV to cat(toSRV, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{_ Begin speaking }\r\n\r\nYou have transferred\r\n\r\n{if len(toShip) > 0:\r\n {List(toShip)} to {OneOf(ShipName(), \"your ship\")}\r\n}\r\n\r\n{if len(toCarrier) > 0:\r\n {if len(toShip) > 0: and }\r\n {List(toCarrier)} to {OneOf(carrier.name, \"your carrier\")}\r\n}\r\n\r\n{if len(toSRV) > 0:\r\n {if len(toShip) > 0: and }\r\n {List(toSRV)} to your SRV\r\n}.\r\n",
"default": true,
"name": "Cargo transfer",
"description": "Triggered when transferring commodities between your ship, SRV, or carrier"
},
"Cargo wingupdate": {
"enabled": true,
"priority": 3,
Expand Down
9 changes: 9 additions & 0 deletions SpeechResponder/eddi.es.json
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,15 @@
"name": "Cargo scoop",
"description": "Triggered when you deploy or retract your cargo scoop"
},
"Cargo transfer": {
"enabled": true,
"priority": 3,
"responder": true,
"script": "{_ Set up a simple function to create descriptions for each transferred commodity }\r\n\r\n{set parseItem(cargo) to:\r\n {if cargo.amount = 1: \r\n {set tonnes to \" tonne \"}\r\n |else: \r\n {set tonnes to \" tonnes \"}\r\n }\r\n {set item to cat(cargo.amount, tonnes, \" of \", cargo.commodity)}\r\n {return item}\r\n}\r\n\r\n{_ Generate lists of transfer descriptions for each of the possible locations }\r\n\r\n{if len(event.toship) > 0:\r\n {set toShip to []}\r\n {for cargo in event.toship:\r\n {set toShip to cat(toShip, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{if len(event.tocarrier) > 0:\r\n {set toCarrier to []}\r\n {for cargo in event.tocarrier:\r\n {set toCarrier to cat(toCarrier, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{if len(event.tosrv) > 0:\r\n {set toSRV to []}\r\n {for cargo in event.tosrv:\r\n {set toSRV to cat(toSRV, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{_ Begin speaking }\r\n\r\nYou have transferred\r\n\r\n{if len(toShip) > 0:\r\n {List(toShip)} to {OneOf(ShipName(), \"your ship\")}\r\n}\r\n\r\n{if len(toCarrier) > 0:\r\n {if len(toShip) > 0: and }\r\n {List(toCarrier)} to {OneOf(carrier.name, \"your carrier\")}\r\n}\r\n\r\n{if len(toSRV) > 0:\r\n {if len(toShip) > 0: and }\r\n {List(toSRV)} to your SRV\r\n}.\r\n",
"default": true,
"name": "Cargo transfer",
"description": "Triggered when transferring commodities between your ship, SRV, or carrier"
},
"Cargo wingupdate": {
"enabled": true,
"priority": 3,
Expand Down
9 changes: 9 additions & 0 deletions SpeechResponder/eddi.fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@
"name": "Cargo scoop",
"description": "Triggered when you deploy or retract your cargo scoop"
},
"Cargo transfer": {
"enabled": true,
"priority": 3,
"responder": true,
"script": "{_ Set up a simple function to create descriptions for each transferred commodity }\r\n\r\n{set parseItem(cargo) to:\r\n {if cargo.amount = 1: \r\n {set tonnes to \" tonne \"}\r\n |else: \r\n {set tonnes to \" tonnes \"}\r\n }\r\n {set item to cat(cargo.amount, tonnes, \" of \", cargo.commodity)}\r\n {return item}\r\n}\r\n\r\n{_ Generate lists of transfer descriptions for each of the possible locations }\r\n\r\n{if len(event.toship) > 0:\r\n {set toShip to []}\r\n {for cargo in event.toship:\r\n {set toShip to cat(toShip, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{if len(event.tocarrier) > 0:\r\n {set toCarrier to []}\r\n {for cargo in event.tocarrier:\r\n {set toCarrier to cat(toCarrier, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{if len(event.tosrv) > 0:\r\n {set toSRV to []}\r\n {for cargo in event.tosrv:\r\n {set toSRV to cat(toSRV, [parseItem(cargo)])}\r\n }\r\n}\r\n\r\n{_ Begin speaking }\r\n\r\nYou have transferred\r\n\r\n{if len(toShip) > 0:\r\n {List(toShip)} to {OneOf(ShipName(), \"your ship\")}\r\n}\r\n\r\n{if len(toCarrier) > 0:\r\n {if len(toShip) > 0: and }\r\n {List(toCarrier)} to {OneOf(carrier.name, \"your carrier\")}\r\n}\r\n\r\n{if len(toSRV) > 0:\r\n {if len(toShip) > 0: and }\r\n {List(toSRV)} to your SRV\r\n}.\r\n",
"default": true,
"name": "Cargo transfer",
"description": "Triggered when transferring commodities between your ship, SRV, or carrier"
},
"Cargo wingupdate": {
"enabled": true,
"priority": 3,
Expand Down
Loading

0 comments on commit b6ae82b

Please sign in to comment.