2
0
mirror of https://github.com/9ParsonsB/Pulsar.git synced 2025-04-05 17:39:39 -04:00
pulsar/Pulsar/Utils/JournalJsonConverter.cs
Ben Parsons 2ac1a927ca Update Status, Power now look nice, also shows est refuel time
Status now shows alerts when taking damage
JournalService support more journals
Added enums to frontend, not quite working
Added More examples to Explorer component
2024-05-15 01:00:56 +10:00

354 lines
17 KiB
C#

using Observatory.Framework.Files.Journal.Combat;
using Observatory.Framework.Files.Journal.Exploration;
using Observatory.Framework.Files.Journal.Odyssey;
using Observatory.Framework.Files.Journal.Other;
using Observatory.Framework.Files.Journal.Powerplay;
using Observatory.Framework.Files.Journal.Startup;
using Observatory.Framework.Files.Journal.StationServices;
using Observatory.Framework.Files.Journal.Trade;
using Observatory.Framework.Files.Journal.Travel;
namespace Pulsar.Utils;
using Observatory.Framework.Files.Journal;
[Flags]
public enum JournalReaderState
{
/// <summary>
/// Have read the first character of the object
/// </summary>
Start,
/// <summary>
/// Have read the timestamp. Generally the first property in a journal entry.
/// </summary>
Timestamp,
/// <summary>
/// have read the event name. Generally the second property in a journal entry.
/// </summary>
Event,
/// <summary>
/// Have read the last character of the object, the next character should be a newline, whitespace, EOF, or another object.
/// </summary>
End,
}
/// <summary>
/// A JournalFile contains a collection of journal entries.
/// Each journal entry is a JSON object, delimited by a newline character.
/// all Journals can be deserialized into a JournalBase object for identification
/// and then deserialized into their respective types.
/// </summary>
public class JournalConverter(ILogger logger) : JsonConverter<JournalBase>
{
private JournalReaderState state = JournalReaderState.Start;
public override JournalBase? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Utf8JsonReader clone = reader;
DateTimeOffset? timestamp = null;
string? eventName = null;
// for debug
int depth = 0;
do
{
depth++;
switch (clone.TokenType)
{
case JsonTokenType.None:
break;
case JsonTokenType.StartObject:
state = JournalReaderState.Start;
break;
case JsonTokenType.EndObject:
state = JournalReaderState.End;
break;
case JsonTokenType.StartArray:
break;
case JsonTokenType.EndArray:
break;
case JsonTokenType.PropertyName:
var propertyName = clone.GetString();
// if we have not started reading the body, and we have not read the (timestamp or event name)
if ((state & JournalReaderState.Timestamp) == 0 || (state & JournalReaderState.Event) == 0)
{
switch (propertyName)
{
case "timestamp":
clone.Read();
timestamp = clone.GetDateTimeOffset();
state = JournalReaderState.Timestamp;
break;
case "event":
clone.Read();
eventName = clone.GetString();
state = JournalReaderState.Event;
break;
}
}
if ((state & JournalReaderState.Event) != 0)
{
// create destination type
return GetDestinationType(ref reader, eventName!);
}
break;
case JsonTokenType.Comment:
continue;
case JsonTokenType.String:
break;
case JsonTokenType.Number:
break;
case JsonTokenType.True:
break;
case JsonTokenType.False:
break;
case JsonTokenType.Null:
break;
default:
throw new ArgumentOutOfRangeException();
}
} while (clone.Read());
return new() { Timestamp = timestamp!.Value, Event = eventName! };
// TODO: handle inf (invalid data) in the journal files
// else if (typeof(TJournal) == typeof(Scan) && json.Contains("\"RotationPeriod\":inf"))
// {
// deserialized = JsonSerializer.Deserialize<TJournal>(json.Replace("\"RotationPeriod\":inf,", ""));
// }
}
private JournalBase GetDestinationType(ref Utf8JsonReader reader, string eventName)
{
switch (eventName.ToLower())
{
case "fileheader":
return JsonSerializer.Deserialize<FileHeader>(ref reader)!;
case "commander":
return JsonSerializer.Deserialize<Commander>(ref reader)!;
case "materials":
return JsonSerializer.Deserialize<Materials>(ref reader)!;
case "rank":
return JsonSerializer.Deserialize<Rank>(ref reader)!;
case "music":
return JsonSerializer.Deserialize<Music>(ref reader)!;
case "cargo":
return JsonSerializer.Deserialize<Cargo>(ref reader)!;
case "loadout":
return JsonSerializer.Deserialize<Loadout>(ref reader)!;
case "missions":
return JsonSerializer.Deserialize<Missions>(ref reader)!;
case "fsssignaldiscovered":
return JsonSerializer.Deserialize<FSSSignalDiscovered>(ref reader)!;
case "reputation":
return JsonSerializer.Deserialize<Reputation>(ref reader)!;
case "loadgame":
return JsonSerializer.Deserialize<LoadGame>(ref reader)!;
case "receivetext":
return JsonSerializer.Deserialize<ReceiveText>(ref reader)!;
case "shiplocker":
return JsonSerializer.Deserialize<ShipLockerMaterials>(ref reader)!;
case "location":
return JsonSerializer.Deserialize<Location>(ref reader)!;
case "powerplay":
return JsonSerializer.Deserialize<Powerplay>(ref reader)!;
case "reservoirreplenished":
return JsonSerializer.Deserialize<ReservoirReplenished>(ref reader)!;
case "statistics":
return JsonSerializer.Deserialize<Statistics>(ref reader)!;
case "scan":
return JsonSerializer.Deserialize<Scan>(ref reader)!;
case "shipyard":
return JsonSerializer.Deserialize<Shipyard>(ref reader)!;
case "docked":
return JsonSerializer.Deserialize<Docked>(ref reader)!;
case "leavebody":
return JsonSerializer.Deserialize<LeaveBody>(ref reader)!;
case "progress":
return JsonSerializer.Deserialize<Progress>(ref reader)!;
case "supercruiseexit":
return JsonSerializer.Deserialize<SupercruiseExit>(ref reader)!;
case "engineerprogress":
return JsonSerializer.Deserialize<EngineerProgress>(ref reader)!;
case "dockingrequested":
return JsonSerializer.Deserialize<DockingRequested>(ref reader)!;
case "npccrewpaidwage":
return JsonSerializer.Deserialize<NpcCrewPaidWage>(ref reader)!;
case "supercruiseentry":
return JsonSerializer.Deserialize<SupercruiseEntry>(ref reader)!;
case "dockinggranted":
return JsonSerializer.Deserialize<DockingGranted>(ref reader)!;
case "startjump":
return JsonSerializer.Deserialize<StartJump>(ref reader)!;
case "fssallbodiesfound":
return JsonSerializer.Deserialize<FSSAllBodiesFound>(ref reader)!;
case "fssbodysignals":
return JsonSerializer.Deserialize<FSSBodySignals>(ref reader)!;
case "liftoff":
return JsonSerializer.Deserialize<Liftoff>(ref reader)!;
case "supercruisedestinationdrop":
return JsonSerializer.Deserialize<SupercruiseDestinationDrop>(ref reader)!;
case "fsdtarget":
return JsonSerializer.Deserialize<FSDTarget>(ref reader)!;
case "fsdjump":
return JsonSerializer.Deserialize<FSDJump>(ref reader)!;
case "codexentry":
return JsonSerializer.Deserialize<CodexEntry>(ref reader)!;
case "hulldamage":
return JsonSerializer.Deserialize<HullDamage>(ref reader)!;
case "materialcollected":
return JsonSerializer.Deserialize<MaterialCollected>(ref reader)!;
case "navroute":
return JsonSerializer.Deserialize<NavRoute>(ref reader)!;
case "navrouteclear":
return JsonSerializer.Deserialize<NavRouteClear>(ref reader)!;
case "scanbarycentre":
return JsonSerializer.Deserialize<ScanBaryCentre>(ref reader)!;
case "jetconeboost":
return JsonSerializer.Deserialize<JetConeBoost>(ref reader)!;
case "shutdown":
return JsonSerializer.Deserialize<Shutdown>(ref reader)!;
case "fuelscoop":
return JsonSerializer.Deserialize<FuelScoop>(ref reader)!;
case "fssdiscoveryscan":
return JsonSerializer.Deserialize<FSSDiscoveryScan>(ref reader)!;
case "moduleinfo":
return JsonSerializer.Deserialize<ModuleInfo>(ref reader)!;
case "shiptargeted":
return JsonSerializer.Deserialize<ShipTargeted>(ref reader)!;
case "afmurepairs":
return JsonSerializer.Deserialize<AfmuRepairs>(ref reader)!;
case "heatwarning":
return JsonSerializer.Deserialize<HeatWarning>(ref reader)!;
case "modulebuy":
return JsonSerializer.Deserialize<ModuleBuy>(ref reader)!;
case "buydrones":
return JsonSerializer.Deserialize<BuyDrones>(ref reader)!;
case "shieldstate":
return JsonSerializer.Deserialize<ShieldState>(ref reader)!;
case "buyammo":
return JsonSerializer.Deserialize<BuyAmmo>(ref reader)!;
case "ejectcargo":
return JsonSerializer.Deserialize<EjectCargo>(ref reader)!;
case "approachbody":
return JsonSerializer.Deserialize<ApproachBody>(ref reader)!;
case "docksrv":
return JsonSerializer.Deserialize<DockSRV>(ref reader)!;
case "touchdown":
return JsonSerializer.Deserialize<Touchdown>(ref reader)!;
case "saasignalsfound":
return JsonSerializer.Deserialize<SAASignalsFound>(ref reader)!;
case "engineercraft":
return JsonSerializer.Deserialize<EngineerCraft>(ref reader)!;
case "materialtrade":
return JsonSerializer.Deserialize<MaterialTrade>(ref reader)!;
case "repair":
return JsonSerializer.Deserialize<Repair>(ref reader)!;
case "refuelall":
return JsonSerializer.Deserialize<RefuelAll>(ref reader)!;
case "storedmodules":
return JsonSerializer.Deserialize<StoredModules>(ref reader)!;
case "synthesis":
return JsonSerializer.Deserialize<Synthesis>(ref reader)!;
case "scanned":
return JsonSerializer.Deserialize<Scanned>(ref reader)!;
case "sendtext":
return JsonSerializer.Deserialize<SendText>(ref reader)!;
case "embark":
return JsonSerializer.Deserialize<Embark>(ref reader)!;
case "multisellexplorationdata":
return JsonSerializer.Deserialize<MultiSellExplorationData>(ref reader)!;
case "backpack":
return JsonSerializer.Deserialize<BackpackMaterials>(ref reader)!;
case "modulesell":
return JsonSerializer.Deserialize<ModuleSell>(ref reader)!;
case "undocked":
return JsonSerializer.Deserialize<Undocked>(ref reader)!;
case "repairall":
return JsonSerializer.Deserialize<RepairAll>(ref reader)!;
case "outfitting":
return JsonSerializer.Deserialize<Outfitting>(ref reader)!;
case "powerplaysalary":
return JsonSerializer.Deserialize<PowerplaySalary>(ref reader)!;
case "redeemvoucher":
return JsonSerializer.Deserialize<RedeemVoucher>(ref reader)!;
case "saascancomplete":
return JsonSerializer.Deserialize<SAAScanComplete>(ref reader)!;
case "friends":
return JsonSerializer.Deserialize<Friends>(ref reader)!;
case "launchsrv":
return JsonSerializer.Deserialize<LaunchSRV>(ref reader)!;
case "suitloadout":
return JsonSerializer.Deserialize<SuitLoadout>(ref reader)!;
case "disembark":
return JsonSerializer.Deserialize<Disembark>(ref reader)!;
case "materialdiscovered":
return JsonSerializer.Deserialize<MaterialDiscovered>(ref reader)!;
case "storedships":
return JsonSerializer.Deserialize<StoredShips>(ref reader)!;
case "scanorganic":
return JsonSerializer.Deserialize<ScanOrganic>(ref reader)!;
case "market":
return JsonSerializer.Deserialize<Market>(ref reader)!;
case "missioncompleted":
return JsonSerializer.Deserialize<MissionCompleted>(ref reader)!;
case "sellshiponrebuy":
return JsonSerializer.Deserialize<SellShipOnRebuy>(ref reader)!;
case "missionaccepted":
return JsonSerializer.Deserialize<MissionAccepted>(ref reader)!;
case "approachsettlement":
return JsonSerializer.Deserialize<ApproachSettlement>(ref reader)!;
case "screenshot":
return JsonSerializer.Deserialize<Screenshot>(ref reader)!;
case "moduleswap":
return JsonSerializer.Deserialize<ModuleSwap>(ref reader)!;
case "underattack":
return JsonSerializer.Deserialize<UnderAttack>(ref reader)!;
case "datascanned":
return JsonSerializer.Deserialize<DataScanned>(ref reader)!;
case "dockingdenied":
return JsonSerializer.Deserialize<DockingDenied>(ref reader)!;
case "fetchremotemodule":
return JsonSerializer.Deserialize<FetchRemoteModule>(ref reader)!;
case "engineercontribution":
return JsonSerializer.Deserialize<EngineerContribution>(ref reader)!;
case "collectcargo":
return JsonSerializer.Deserialize<CollectCargo>(ref reader)!;
case "moduleretrieve":
return JsonSerializer.Deserialize<ModuleRetrieve>(ref reader)!;
case "marketbuy":
return JsonSerializer.Deserialize<MarketBuy>(ref reader)!;
case "selldrones":
return JsonSerializer.Deserialize<SellDrones>(ref reader)!;
case "interdicted":
return JsonSerializer.Deserialize<Interdicted>(ref reader)!;
case "sellorganicdata":
return JsonSerializer.Deserialize<SellOrganicData>(ref reader)!;
case "wingadd":
return JsonSerializer.Deserialize<WingAdd>(ref reader)!;
case "winginvite":
return JsonSerializer.Deserialize<WingInvite>(ref reader)!;
case "wingjoin":
return JsonSerializer.Deserialize<WingJoin>(ref reader)!;
case "wingleave":
return JsonSerializer.Deserialize<WingLeave>(ref reader)!;
case "bounty":
return JsonSerializer.Deserialize<Bounty>(ref reader)!;
case "commitcrime":
return JsonSerializer.Deserialize<CommitCrime>(ref reader)!;
case "modulestore":
return JsonSerializer.Deserialize<ModuleStore>(ref reader)!;
default:
logger.LogWarning("Unknown Journal event type {EventName}", eventName);
return JsonSerializer.Deserialize<JournalBase>(ref reader)!;
}
}
public override void Write(Utf8JsonWriter writer, JournalBase value, JsonSerializerOptions options)
{
throw new NotSupportedException();
}
}